<!doctype html>
<html itemscope itemtype="http://schema.org/WebPage" lang="zh-cn" class="no-js">
  <head>
    <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.121.1">
<link rel="canonical" type="text/html" href="/docs/tutorials/">
<meta name="robots" content="noindex, nofollow">


<link rel="shortcut icon" href="/favicons/favicon.ico" >
<link rel="apple-touch-icon" href="/favicons/apple-touch-icon-180x180.png" sizes="180x180">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/android-36x36.png" sizes="36x36">
<link rel="icon" type="image/png" href="/favicons/android-48x48.png" sizes="48x48">
<link rel="icon" type="image/png" href="/favicons/android-72x72.png" sizes="72x72">
<link rel="icon" type="image/png" href="/favicons/android-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicons/android-144x144.png" sizes="144x144">
<link rel="icon" type="image/png" href="/favicons/android-192x192.png" sizes="192x192">

<title>用户手册 | SOFAServerless</title>
<meta name="description" content="">
<meta property="og:title" content="用户手册" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="/docs/tutorials/" />

<meta itemprop="name" content="用户手册">
<meta itemprop="description" content=""><meta name="twitter:card" content="summary"/><meta name="twitter:title" content="用户手册"/>
<meta name="twitter:description" content=""/>




<link rel="preload" href="/scss/main.min.526354c4efc1a4747972ed64c3be00f7db62aec5f0a3e6ae42052f97e2675d86.css" as="style">
<link href="/scss/main.min.526354c4efc1a4747972ed64c3be00f7db62aec5f0a3e6ae42052f97e2675d86.css" rel="stylesheet" integrity="">

<script
  src="https://code.jquery.com/jquery-3.6.3.min.js"
  integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
  crossorigin="anonymous"></script>
<link rel="stylesheet" href="/css/prism.css"/>
<link href="/img/logo.svg" rel="icon" type="image/svg">
<link href="/search/pagefind-ui.css" rel="stylesheet">
<script src="/search/pagefind-ui.js" type="text/javascript"></script>

<script>
    window.addEventListener('DOMContentLoaded', (event) => {
        new PagefindUI({ element: ".td-search" });
    });
</script>


<script>
var doNotTrack = false;
if (!doNotTrack) {
	window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
	ga('create', 'G-DZ8Q3F0GZ7', 'auto');
	
	ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>

<script async src="https://www.googletagmanager.com/gtag/js?id=G-DZ8Q3F0GZ7"></script>
<script>
var doNotTrack = false;
if (!doNotTrack) {
	window.dataLayer = window.dataLayer || [];
	function gtag(){dataLayer.push(arguments);}
	gtag('js', new Date());
	gtag('config', 'G-DZ8Q3F0GZ7');
}
</script>
  </head>
  <body class="td-section">
    <header>
      <nav class="td-navbar navbar-dark js-navbar-scroll">
<div class="container-fluid flex-column flex-md-row">
  <a class="navbar-brand" href="/"><span class="navbar-brand__logo navbar-logo"><svg width="26" height="29" viewBox="0 0 26 29" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient x1="52.6662558%" y1="95.7312514%" x2="35.7492678%" y2="11.0078657%" id="linearGradient-wxw43fh1xd-1"><stop stop-color="#9822e4" offset="0"/><stop stop-color="#e643fa" offset="86.0585504%"/><stop stop-color="#f876ff" offset="100%"/></linearGradient><path d="M15.9275871 1.54432572 15.936122 1.5594269 15.9445709 1.57457632 5.01248933 7.79418913 7.699 9.304l8.8412359-4.72420311.8668497-.49490764C17.4171462 4.0791454 17.4272394 4.07345885 17.4373647 4.06782987c1.474137-.81952243 3.3335154-.28885241 4.1530379 1.18528466L10.875 11.088l2.864 1.609 8.843271-5.6213813c1.1038914-.6292563 2.5021428-.23250173 3.1230817.88617614C25.8984381 8.30965565 25.9998668 8.70204694 25.9998668 9.10116416V19.9436637c0 1.3476373-1.002317 2.484932-2.3392704 2.6542897L22.9421516 22.6889619V10.4257286L20.457252 12.0257475 20.457758 23.6880152c0 1.2665471-1.0267393 2.2932864-2.2932864 2.2932864H17.59115L17.590252 13.8727475 15.106 15.473 15.1067564 27.0588825c0 1.0695936-.855616100000001 1.9366704-1.911072 1.9366704C12.8696714 28.9955529 12.5490782 28.9110348 12.2643947 28.7500365L1.63270516 23.3171586C.159863707 22.5645249-.423980046 20.7604209.328653641 19.2875794L.372104915 19.2057013 12.0490412 25.0797183 12.049 22.086 1.98952173 16.7675786C.51279311 15.9867912-.0513787599 14.1567129.729408593 12.6799843L.744416289 12.6519572.759717752 12.6240895 12.049 18.593 12.0490412 15.2566254 1.7391964 9.45898637C1.44132502 9.2850324 1.19527431 9.0328708 1.02697438 8.72907568c-.516688418-.93266477-.189466545-2.11320819.7308705-2.63681754C6.19445786 3.56812633 9.52191759 1.67502747 11.7402241.412961569L11.7628911.400065593c1.4660277-.834070345 3.3306257-.321767634 4.164696 1.144260127z" id="path-wxw43fh1xd-2"/><linearGradient x1="50.6099966%" y1="31.6743333%" x2="50.2419846%" y2="73.0702907%" id="linearGradient-wxw43fh1xd-4"><stop stop-color="#8200b5" offset="0"/><stop stop-color="#8200b5" stop-opacity="0" offset="100%"/></linearGradient><linearGradient x1="50.6028666%" y1="31.6743333%" x2="50.2391561%" y2="73.0702907%" id="linearGradient-wxw43fh1xd-5"><stop stop-color="#8200b5" offset="0"/><stop stop-color="#8200b5" stop-opacity="0" offset="100%"/></linearGradient><linearGradient x1="90.8235257%" y1="50%" x2="3.24041867%" y2="52.9415572%" id="linearGradient-wxw43fh1xd-6"><stop stop-color="#dd3ff7" stop-opacity="0" offset="0"/><stop stop-color="#ca23e4" offset="100%"/></linearGradient><linearGradient x1="74.3272776%" y1="35.8586031%" x2="19.6895996%" y2="19.3309621%" id="linearGradient-wxw43fh1xd-7"><stop stop-color="#b800d1" stop-opacity="0" offset="0"/><stop stop-color="#ae00c5" offset="100%"/></linearGradient><linearGradient x1="97.0070676%" y1="71.8003287%" x2="11.3661868%" y2="30.5044309%" id="linearGradient-wxw43fh1xd-8"><stop stop-color="#940ec7" offset="0"/><stop stop-color="#c435f0" stop-opacity="0" offset="100%"/></linearGradient></defs><g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="首页" transform="translate(-24.000000, -18.000000)"><g id="编组-4" transform="translate(24.000133, 16.000000)"><g id="路径-6-copy-2" transform="translate(0.000000, 2.004447)"><mask id="mask-wxw43fh1xd-3" fill="#fff"><use xlink:href="#path-wxw43fh1xd-2"/></mask><use id="Mask" fill="url(#linearGradient-wxw43fh1xd-1)" fill-rule="nonzero" xlink:href="#path-wxw43fh1xd-2"/><path d="M12.0490412 15.2684078 13.03943 15.5167092C14.3279076 16.0478608 15.1686754 17.3038563 15.1686754 18.6975193V18.7421449v9.047164l-3.1196342-1.4070083V15.2684078z" id="Path-114-Copy-2" fill="url(#linearGradient-wxw43fh1xd-4)" opacity=".69047619" mask="url(#mask-wxw43fh1xd-3)"/><path d="M22.9421516 10.4227424 23.8594661 10.2542707C24.8889759 10.219744 25.7876765 10.946368 25.9694916 11.9602841L26.0763097 12.5559692 26.0617858 22.9064645l-3.1196342-1.4070082V10.4227424z" id="Path-114-Copy-2" fill="url(#linearGradient-wxw43fh1xd-5)" opacity=".69047619" mask="url(#mask-wxw43fh1xd-3)"/><polygon id="Path-41" fill="url(#linearGradient-wxw43fh1xd-6)" mask="url(#mask-wxw43fh1xd-3)" points="7.6326499 9.31647968 11.9297751 6.77228295 14.9765833 9.31647968 10.7681311 11.1500753"/><path d="M6.16852974 12.7326226C8.05429918 13.6181711 7.86496926 14.83948 8.18831704 15.006813 8.70089861 15.2720748 9.14143095 17.098905 9.86115602 17.1695013 10.6949216 17.2512836 11.6478081 10.8552079 10.3936906 10.4556578 9.48069361 10.1647855 7.32719679 9.49121213 3.93320016 8.43493769c-.63204609 1.86851711.11306377 3.30107871 2.23532958 4.29768491z" fill="url(#linearGradient-wxw43fh1xd-7)" mask="url(#mask-wxw43fh1xd-3)" transform="translate(7.357416, 12.802608) rotate(-347.000000) translate(-7.357416, -12.802608)"/><polygon id="Path-43" fill="url(#linearGradient-wxw43fh1xd-8)" mask="url(#mask-wxw43fh1xd-3)" points="12.0699788 18.5615749 6.27140769 15.1359473 5.30588708 19.0963147 12.0699788 22.1120507"/></g></g></g></g></svg></span><span class="navbar-brand__name">SOFAServerless</span></a>
  <div class="td-navbar-nav-scroll ms-md-auto" id="main_navbar">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" href="/home/"><span>首页</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link active" href="/docs/"><span>产品文档</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/blog/"><span>最新信息</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/community/"><span>参与社区</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/user-cases/"><span>用户案例</span></a>
      </li>
      <li class="nav-item dropdown d-none d-lg-block">
        <div class="dropdown">
  <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">中文</a>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="/no/"></a></li>
    </ul>
</div></li>
      </ul>
  </div>
  <div class="d-none d-lg-block">
    <div class="td-search">
  <div class="td-search__icon"></div>
  <input type="search" class="td-search__input form-control td-search-input" placeholder="站内搜索…" aria-label="站内搜索…" autocomplete="off">
</div>

  </div>
</div>
</nav>
    </header>
    <div class="container-fluid td-outer">
      <div class="td-main">
        <div class="row flex-xl-nowrap">
          <main class="col-12 col-md-9 col-xl-8 ps-md-5" role="main">
            




<div class="td-content">
<div class="pageinfo pageinfo-primary d-print-none">
<p>
这是本节的多页打印视图。
<a href="#" onclick="print();return false;">点击此处打印</a>.
</p><p>
<a href="/docs/tutorials/">返回本页常规视图</a>.
</p>
</div>



<h1 class="title">用户手册</h1>





    <ul>
    
  
  
  
  

  
    
    
	
<li>1: <a href="#pg-85d651fc55ba7dc800d677008a2c7fa5">基座接入</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>1.1: <a href="#pg-18b872e057bed8156d471e220e894432">SpringBoot 或 SOFABoot 升级为基座</a></li>


    
  

    </ul>
    
  
    
    
	
<li>2: <a href="#pg-144d016bb7fc7652017580bd4bbe4e56">模块接入</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>2.1: <a href="#pg-efab46696dc71baece82293194586ad3">SpringBoot 或 SOFABoot 一键升级为模块</a></li>


    
  
    
    
	
<li>2.2: <a href="#pg-0f5b7bcef23427d2a6a0c1fcaca9ad4a">使用 maven archtype 脚手架自动生成</a></li>


    
  

    </ul>
    
  
    
    
	
<li>3: <a href="#pg-386a856dc258ab2701435ac4609b80fe">基座与模块并行开发验证</a></li>


    
  
    
    
	
<li>4: <a href="#pg-1338dd6d363fcbe1552c858a20719417">模块研发</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>4.1: <a href="#pg-bf65e93b734e75f456eb02447ae9f065">编码规范</a></li>


    
  
    
    
	
<li>4.2: <a href="#pg-6e3cbd7799f1397ab7793638f56a6f1a">模块瘦身</a></li>


    
  
    
    
	
<li>4.3: <a href="#pg-66b2590d54145be7fd0f895684bc34ef">模块与模块、模块与基座通信</a></li>


    
  
    
    
	
<li>4.4: <a href="#pg-e829d04a9debc230b4d695f03971b67b">模块本地开发</a></li>


    
  
    
    
	
<li>4.5: <a href="#pg-28a800d400556ead949da2297e04f900">模块测试</a></li>


    
  
    
    
	
<li>4.6: <a href="#pg-037484c6b7708a4128ecdd19d8578aaa">复用基座拦截器</a></li>


    
  
    
    
	
<li>4.7: <a href="#pg-06ace3863ce3b10117de52a241f0d9e0">复用基座数据源</a></li>


    
  
    
    
	
<li>4.8: <a href="#pg-4a763f2560193bc6f6a4c64874383f22">静态合并部署</a></li>


    
  
    
    
	
<li>4.9: <a href="#pg-dbe415e386e1bcdf1f3e7a62a91e6eb6">模块中官方支持的中间件客户端</a></li>


    
  
    
    
	
<li>4.10: <a href="#pg-4c134980130d1dc3c830b9224a754361">SOFAArk 关键用户文档</a></li>


    
  

    </ul>
    
  
    
    
	
<li>5: <a href="#pg-307f45cbc34bd56c2422e01b460303bb">模块运维</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>5.1: <a href="#pg-f274515d3bf16798aa419325f53c707a">模块上线与下线</a></li>


    
  
    
    
	
<li>5.2: <a href="#pg-7b5bd50a9b9adfe3d8e27a3a4117e738">模块发布</a></li>


    
  
    
    
	
<li>5.3: <a href="#pg-03f7fcbe7eb355b82c98153891be1e48">基座和模块不兼容发布</a></li>


    
  
    
    
	
<li>5.4: <a href="#pg-ac1464ebc2e0083dd90ccb0c00118fca">模块扩缩容与替换</a></li>


    
  
    
    
	
<li>5.5: <a href="#pg-7011e375d7565bd7cea7f9347f8e8c9e">模块发布运维策略</a></li>


    
  
    
    
	
<li>5.6: <a href="#pg-24eb3a9c0234e21473eec787d4ae6d7a">独立使用 Arklet</a></li>


    
  
    
    
	
<li>5.7: <a href="#pg-c588ae48a684af6c4c57ee4d9aae6ce4">模块信息查看</a></li>


    
  
    
    
	
<li>5.8: <a href="#pg-cbb99adb1eb306a588e034d68e0481d8">模块Service</a></li>


    
  
    
    
	
<li>5.9: <a href="#pg-68c3bb9b1561f186515e61704fac5511">所有 K8S 资源定义及部署方式</a></li>


    
  

    </ul>
    
  

    </ul>


<div class="content">
      
</div>
</div>


  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-85d651fc55ba7dc800d677008a2c7fa5">1 - 基座接入</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-18b872e057bed8156d471e220e894432">1.1 - SpringBoot 或 SOFABoot 升级为基座</h1>
    
	<h2 id="前提条件">前提条件</h2>
<ol>
<li>SpringBoot 版本 &gt;= 2.3.0（针对 SpringBoot 用户）</li>
<li>SOFABoot 版本 &gt;= 3.9.0 或 SOFABoot &gt;= 4.0.0（针对 SOFABoot 用户）</li>
</ol>
<h2 id="接入步骤">接入步骤</h2>
<h3 id="代码与配置修改">代码与配置修改</h3>
<h4 id="修改-applicationproperties">修改 application.properties</h4>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 需要定义应用名</span>
</span></span><span style="display:flex;"><span><span style="color:#c4a000">spring.application.name</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#4e9a06">${替换为实际基座应用名}</span>
</span></span></code></pre></div><h4 id="修改主-pomxml">修改主 pom.xml</h4>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;properties&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;sofa.ark.verion&gt;</span>2.2.5<span style="color:#204a87;font-weight:bold">&lt;/sofa.ark.verion&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;sofa.serverless.runtime.version&gt;</span>0.5.3<span style="color:#204a87;font-weight:bold">&lt;/sofa.serverless.runtime.version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/properties&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa.serverless<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-serverless-base-starter<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>${sofa.serverless.runtime.version}<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/dependency&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">&lt;!-- 如果使用了 springboot web，则加上这个依赖，详细查看https://www.sofastack.tech/projects/sofa-boot/sofa-ark-multi-web-component-deploy/ --&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>web-ark-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/dependency&gt;</span>
</span></span></code></pre></div><h3 id="启动验证">启动验证</h3>
<p>基座应用能正常启动即表示验证成功！</p>
<br/>
<br/>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-144d016bb7fc7652017580bd4bbe4e56">2 - 模块接入</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-efab46696dc71baece82293194586ad3">2.1 - SpringBoot 或 SOFABoot 一键升级为模块</h1>
    
	<p>本文讲解了 SpringBoot 或 SOFABoot 一键升级为模块的操作和验证步骤，仅需加一个 ark 打包插件即可实现普通应用一键升级为模块应用，并且能做到同一套代码分支，既能像原来 SpringBoot 一样独立启动，也能作为模块与其它应用合并部署在一起启动。</p>
<h2 id="前提条件">前提条件</h2>
<ol>
<li>SpringBoot 版本 &gt;= 2.3.0（针对 SpringBoot 用户）</li>
<li>SOFABoot &gt;= 3.9.0 或 SOFABoot &gt;= 4.0.0（针对 SOFABoot 用户）</li>
</ol>
<h2 id="接入步骤">接入步骤</h2>
<h3 id="步骤-1修改-applicationproperties">步骤 1：修改 application.properties</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 需要定义应用名</span>
</span></span><span style="display:flex;"><span><span style="color:#c4a000">spring.application.name</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#4e9a06">${替换为实际模块应用名}</span>
</span></span></code></pre></div><h3 id="步骤-2添加模块需要的依赖和打包插件">步骤 2：添加模块需要的依赖和打包插件</h3>
<p><strong>特别注意</strong>： sofa ark 插件定义顺序必须在 springboot 打包插件前;</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;plugins&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8f5902;font-style:italic">&lt;!--这里添加ark 打包插件--&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-ark-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>{sofa.ark.version}<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;id&gt;</span>default-cli<span style="color:#204a87;font-weight:bold">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#204a87;font-weight:bold">&lt;goal&gt;</span>repackage<span style="color:#204a87;font-weight:bold">&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;skipArkExecutable&gt;</span>true<span style="color:#204a87;font-weight:bold">&lt;/skipArkExecutable&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;outputDirectory&gt;</span>./target<span style="color:#204a87;font-weight:bold">&lt;/outputDirectory&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;bizName&gt;</span>${替换为模块名}<span style="color:#204a87;font-weight:bold">&lt;/bizName&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;webContextPath&gt;</span>${模块自定义的 web context path}<span style="color:#204a87;font-weight:bold">&lt;/webContextPath&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;declaredMode&gt;</span>true<span style="color:#204a87;font-weight:bold">&lt;/declaredMode&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8f5902;font-style:italic">&lt;!--  构建出普通 SpringBoot fatjar，支持独立部署时使用，如果不需要可以删除  --&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#8f5902;font-style:italic">&lt;!--原来 spring-boot 打包插件 --&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>org.springframework.boot<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>spring-boot-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/plugins&gt;</span>
</span></span></code></pre></div><h3 id="步骤-3自动化瘦身模块">步骤 3：自动化瘦身模块</h3>
<p>您可以使用 ark 打包插件的自动化瘦身能力，自动化瘦身模块应用里的 maven 依赖。这一步是必选的，否则构建出的模块 jar 包会非常大，而且启动会报错。
<em>扩展阅读</em>：如果模块不做依赖瘦身<a href="/docs/faq/import-full-springboot-in-module">独立引入 SpringBoot 框架会怎样？</a></p>
<h3 id="步骤-4构建成模块-jar-包">步骤 4：构建成模块 jar 包</h3>
<p>执行 <code>mvn clean package -DskipTest</code>, 可以在 target 目录下找到打包生成的 ark biz jar 包，也可以在 target/boot 目录下找到打包生成的普通的 springboot jar 包。</p>
<p><strong>小贴士</strong>：<a href="/docs/tutorials/module-development/runtime-compatibility-list/">模块中支持的完整中间件清单</a>。</p>
<h2 id="实验验证模块既能独立启动也能被合并部署">实验：验证模块既能独立启动，也能被合并部署</h2>
<p>增加模块打包插件（sofa-ark-maven-plugin）进行打包后，只会新增 ark-biz.jar 构建产物，与原生 spring-boot-maven-plugin 打包的可执行Jar 互相不冲突、不影响。
当服务器部署时，期望独立启动，就使用原生 spring-boot-maven-plugin 构建出的可执行 Jar 作为构建产物；期望作为 ark 模块部署到基座中时，就使用 sofa-ark-maven-plugin 构建出的 xxx-ark-biz.jar 作为构建产物</p>
<h3 id="验证能合并部署到基座上">验证能合并部署到基座上</h3>
<ol>
<li>启动上一步（验证能独立启动步骤）的基座</li>
<li>发起模块部署</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl --location --request POST <span style="color:#4e9a06">&#39;localhost:1238/installBiz&#39;</span> <span style="color:#4e9a06">\
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span>--header <span style="color:#4e9a06">&#39;Content-Type: application/json&#39;</span> <span style="color:#4e9a06">\
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span>--data <span style="color:#4e9a06">&#39;{
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06">    &#34;bizName&#34;: &#34;${模块名}&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06">    &#34;bizVersion&#34;: &#34;${模块版本}&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06">    &#34;bizUrl&#34;: &#34;file:///path/to/ark/biz/jar/target/xx-xxxx-ark-biz.jar&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06">}&#39;</span>
</span></span></code></pre></div><p>返回如下信息表示模块安装成功<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1695021262517-34e6728e-b39e-4996-855b-d866e839fd0a.png#clientId=ueb52f3f0-186e-4&amp;from=paste&amp;height=226&amp;id=u8ab265a1&amp;originHeight=452&amp;originWidth=1818&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=60390&amp;status=done&amp;style=none&amp;taskId=uf3b43b8e-80dd-43db-b486-3ca38663e5e&amp;title=&amp;width=909" alt="image.png"></p>
<ol start="3">
<li>查看当前模块信息，除了基座 base 以外，还存在一个模块 dynamic-provider</li>
</ol>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1695021372335-9fbce7ae-ab41-44e8-ab51-6a771bddfef3.png#clientId=ueb52f3f0-186e-4&amp;from=paste&amp;height=367&amp;id=u301dd5fb&amp;originHeight=734&amp;originWidth=1186&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=97949&amp;status=done&amp;style=none&amp;taskId=u8570e201-b10d-460a-946a-d9c94529834&amp;title=&amp;width=593" alt="image.png"></p>
<ol start="4">
<li>卸载模块</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#a40000">curl</span> <span style="color:#a40000">--location</span> <span style="color:#a40000">--request</span> <span style="color:#a40000">POST</span> <span style="color:#a40000">&#39;localhost:</span><span style="color:#0000cf;font-weight:bold">1238</span><span style="color:#a40000">/uninstallBiz&#39;</span> <span style="color:#a40000">\</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">--header</span> <span style="color:#a40000">&#39;Content-Type:</span> <span style="color:#a40000">application/json&#39;</span> <span style="color:#a40000">\</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">--data</span> <span style="color:#a40000">&#39;</span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span><span style="color:#a40000">&#39;</span>
</span></span></code></pre></div><p>返回如下，表示卸载成功</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;Uninstall biz: dynamic-provider:0.0.1-SNAPSHOT success.&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="验证能独立启动">验证能独立启动</h3>
<p>普通应用改造成模块之后，还是可以独立启动，可以验证一些基本的启动逻辑，只需要在启动配置里勾选自动添加 <code>provided</code>scope 到 classPath 即可，后启动方式与普通应用方式一致。通过自动瘦身改造的模块，也可以在 <code>target/boot</code> 目录下直接通过 springboot jar 包启动，<a href="https://github.com/sofastack/sofa-serverless/blob/module-slimming/samples/springboot-samples/slimming">点击此处</a>查看详情。<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1695032642009-a5248a99-d91b-4420-b830-600b35eaa402.png#clientId=u4eb3445f-d3dc-4&amp;from=paste&amp;height=606&amp;id=ued085b28&amp;originHeight=1212&amp;originWidth=1676&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=169283&amp;status=done&amp;style=none&amp;taskId=u78d21e68-c71c-42d1-ac4c-8b41381bfa4&amp;title=&amp;width=838" alt="image.png"></p>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-0f5b7bcef23427d2a6a0c1fcaca9ad4a">2.2 - 使用 maven archtype 脚手架自动生成</h1>
    
	<p>正在更新中，预计 11 月上线。</p>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-386a856dc258ab2701435ac4609b80fe">3 - 基座与模块并行开发验证</h1>
    
	<p>欢迎使用 <strong>SOFAServerless 完成多 SpringBoot 应用合并部署与动态更新模块</strong>！本文将详细介绍操作流程与方法，希望能够帮助大家节省资源、提高研发效率。
首先，利用 SOFAServerless 完成合并部署与动态更新模块，适用于两种典型场景：</p>
<ol>
<li><strong>合并部署</strong></li>
<li><strong>中台应用</strong><em>（该场景需要先完成合并部署，再完成中台应用 demo)</em></li>
</ol>
<blockquote>
<p>本文实验工程代码在：<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/web/tomcat">开源仓库 samples 目录库里</a></p>
</blockquote>
<h2 id="场景一合并部署">场景一：合并部署</h2>
<p>先介绍第一个场景<strong>多应用合并部署</strong>，整体流程如下:
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/96256555/1700728867593-5f85b5a6-254c-44f9-9866-03f75cd1a30e.png#clientId=u236ce451-8502-4&amp;from=paste&amp;height=596&amp;id=ud7c32f07&amp;originHeight=1192&amp;originWidth=2386&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=2443895&amp;status=done&amp;style=none&amp;taskId=uf8f160d5-4794-4459-aa18-118e3895bff&amp;title=&amp;width=1193" alt="image.png"></p>
<p>可以看到，整体上需要完成的动作是<strong>基座/模块接入改造后进行开发与验证</strong>，而基座与模块的合并部署动作都是可以并行的。接下来我们将逐步介绍操作细节。</p>
<h3 id="1-基座接入改造">1. 基座接入改造</h3>
<ol>
<li>为 **application.properties **增加应用名（如果没有的话）：</li>
</ol>
<p><code>spring.application.name=${基座应用名}</code></p>
<ol start="2">
<li>在 **pom.xml **里增加必要的依赖</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;properties&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;sofa.serverless.runtime.version&gt;</span>0.5.3<span style="color:#204a87;font-weight:bold">&lt;/sofa.serverless.runtime.version&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/properties&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;dependencies&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa.serverless<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-serverless-base-starter<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>${sofa.serverless.runtime.version}<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/dependency&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/dependencies&gt;</span>
</span></span></code></pre></div><hr>
<p>理论上增加这个依赖就可以了，但由于本 demo 需要演示多个 web 模块应用使用一个端口合并部署，需要再引入 <code>web-ark-plugin</code> 依赖，<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-multi-web-component-deploy/">详细原理查看这里</a>。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>web-ark-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/dependency&gt;</span>
</span></span></code></pre></div><ol start="3">
<li>点击编译器启动基座。</li>
</ol>
<h3 id="2-模块-1-接入改造">2. 模块 1 接入改造</h3>
<ol>
<li>添加模块需要的依赖和打包插件</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#a40000">&lt;plugins&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;!--这里添加ark</span> <span style="color:#a40000">打包插件--&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;groupId&gt;com.alipay.sofa&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;artifactId&gt;sofa-ark-maven-plugin&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#a40000">&lt;id&gt;default-cli&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#a40000">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#a40000">&lt;goal&gt;repackage&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#a40000">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;skipArkExecutable&gt;</span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#a40000">&lt;/skipArkExecutable&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;outputDirectory&gt;./target&lt;/outputDirectory&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;bizName&gt;$</span><span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">替换为模块名</span><span style="color:#000;font-weight:bold">}</span><span style="color:#a40000">&lt;/bizName&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;webContextPath&gt;$</span><span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">模块自定义的</span> <span style="color:#a40000">web</span> <span style="color:#a40000">context</span> <span style="color:#a40000">path，需要与其他模块不同</span><span style="color:#000;font-weight:bold">}</span><span style="color:#a40000">&lt;/webContextPath&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;declaredMode&gt;</span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#a40000">&lt;/declaredMode&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a40000">&lt;!--</span>  <span style="color:#a40000">配置模块自动排包列表，从</span> <span style="color:#a40000">github</span> <span style="color:#a40000">下载</span> <span style="color:#a40000">rules.txt，并放在模块根目录的</span> <span style="color:#a40000">conf/ark/</span> <span style="color:#a40000">目录下，下载地址：https:</span><span style="color:#8f5902;font-style:italic">//github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/slimming/log4j2/biz1/conf/ark/rules.txt  --&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>            <span style="color:#a40000">&lt;packExcludesConfig&gt;rules.txt&lt;/packExcludesConfig&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;!--</span>  <span style="color:#a40000">构建出普通</span> <span style="color:#a40000">SpringBoot</span> <span style="color:#a40000">fatjar，支持独立部署时使用，如果不需要可以删除</span>  <span style="color:#a40000">--&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;!--原来</span> <span style="color:#a40000">spring-boot</span> <span style="color:#a40000">打包插件</span> <span style="color:#a40000">--&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">&lt;/plugins&gt;</span>
</span></span></code></pre></div><ol start="2">
<li>
<p>参考官网模块瘦身里<a href="https://sofaserverless.gitee.io/docs/tutorials/module-development/module-slimming/#%E4%B8%80%E9%94%AE%E8%87%AA%E5%8A%A8%E7%98%A6%E8%BA%AB">自动排包部分</a>，下载排包配置文件 <strong>rules.txt</strong>，放在在 <strong>conf/ark/</strong> 目录下</p>
</li>
<li>
<p>开发模块，例如增加 Rest Controller，提供 Rest 接口</p>
</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#a40000">@RestController</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">public</span> <span style="color:#a40000">class</span> <span style="color:#a40000">SampleController</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">private</span> <span style="color:#a40000">static</span> <span style="color:#a40000">final</span> <span style="color:#a40000">Logger</span> <span style="color:#a40000">LOGGER</span> <span style="color:#a40000">=</span> <span style="color:#a40000">LoggerFactory.getLogger(SampleController.class);</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">@Autowired</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">private</span> <span style="color:#a40000">ApplicationContext</span> <span style="color:#a40000">applicationContext;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">@RequestMapping(value</span> <span style="color:#a40000">=</span> <span style="color:#204a87;font-weight:bold">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">method</span> <span style="color:#a40000">=</span> <span style="color:#a40000">RequestMethod.GET)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">public</span> <span style="color:#a40000">String</span> <span style="color:#a40000">hello()</span> <span style="color:#a40000">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">String</span> <span style="color:#a40000">appName</span> <span style="color:#a40000">=</span> <span style="color:#a40000">applicationContext.getApplicationName();</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">LOGGER.info(</span><span style="color:#204a87;font-weight:bold">&#34;{} web test: into sample controller&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">appName);</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">return</span> <span style="color:#a40000">String.format(</span><span style="color:#204a87;font-weight:bold">&#34;hello to %s deploy&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">appName);</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">}</span>
</span></span></code></pre></div><ol start="4">
<li>
<p><a href="https://github.com/sofastack/sofa-serverless/releases/tag/arkctl-release-0.1.0">点击这里下载 Arkctl</a>，mac/linux 电脑放入 <code>**/usr/local/bin**</code> 目录中，windows 可以考虑直接放在项目根目录下</p>
</li>
<li>
<p>执行 <code>arkctl deploy</code> 构建部署，成功后 <code>curl localhost:8080/${模块1 web context path}/</code> 验证服务返回。显示正常，进入下一步。</p>
</li>
</ol>
<pre tabindex="0"><code>hello to ${模块1名} deploy
</code></pre><h3 id="3-模块-1-开发与验证">3. 模块 1 开发与验证</h3>
<p>开发与验证需要完成<strong>修改代码并发布 V2 版本</strong>。具体操作如下：</p>
<ol>
<li>修改 Rest 代码</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#a40000">@RestController</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">public</span> <span style="color:#a40000">class</span> <span style="color:#a40000">SampleController</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">private</span> <span style="color:#a40000">static</span> <span style="color:#a40000">final</span> <span style="color:#a40000">Logger</span> <span style="color:#a40000">LOGGER</span> <span style="color:#a40000">=</span> <span style="color:#a40000">LoggerFactory.getLogger(SampleController.class);</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">@Autowired</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">private</span> <span style="color:#a40000">ApplicationContext</span> <span style="color:#a40000">applicationContext;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">@RequestMapping(value</span> <span style="color:#a40000">=</span> <span style="color:#204a87;font-weight:bold">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">method</span> <span style="color:#a40000">=</span> <span style="color:#a40000">RequestMethod.GET)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a40000">public</span> <span style="color:#a40000">String</span> <span style="color:#a40000">hello()</span> <span style="color:#a40000">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">String</span> <span style="color:#a40000">appName</span> <span style="color:#a40000">=</span> <span style="color:#a40000">applicationContext.getApplicationName();</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">LOGGER.info(</span><span style="color:#204a87;font-weight:bold">&#34;{} web test v2: into sample controller&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">appName);</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a40000">return</span> <span style="color:#a40000">String.format(</span><span style="color:#204a87;font-weight:bold">&#34;hello to %s deploy v2&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#a40000">appName);</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">}</span>
</span></span></code></pre></div><ol start="2">
<li>执行 <code>arkctl deploy</code> 构建部署，成功后 <code>curl localhost:8080/${模块1 web context path}/</code> 验证服务返回</li>
</ol>
<pre tabindex="0"><code>hello to ${模块1名} deploy v2
</code></pre><h3 id="4-模块-2-接入改造开发与验证">4. 模块 2 接入改造、开发与验证</h3>
<p>模块 2 同样采用上述步骤2⃣️3⃣️，即模块 1 接入改造与验证的操作流程。</p>
<h2 id="场景二中台应用">场景二：中台应用</h2>
<p>中台应用的特点是<strong>基座有复杂的编排逻辑</strong>去定义<strong>对外暴露服务和业务所需的 SPI</strong>。模块应用来实现这些 SPI 接口，往往会对一个接口在多个模块里定义多个不同的实现。整体流程如下：
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/96256555/1700706388244-f46fbd3d-262d-4a9d-894a-243782860cce.png#clientId=ue666f90d-083a-4&amp;from=paste&amp;height=310&amp;id=u76e59b07&amp;originHeight=620&amp;originWidth=1762&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=345022&amp;status=done&amp;style=none&amp;taskId=ue115f7a7-de5a-4c01-91d4-0965c2422dc&amp;title=&amp;width=881" alt="image.png"></p>
<p>可以看到，与场景一合并部署操作不同的是，需要在<strong>基座</strong>接入改造与开发验证中间新增一步<strong>通信类和 SPI 的定义</strong>；<strong>模块</strong>接入改造与开发验证中间新增一步<strong>引入通信类基座并实现基座 SPI</strong>。
<strong>接下来我们将介绍与合并部署不同的</strong><em><strong>（即新增的）</strong></em><strong>操作细节。</strong></p>
<h3 id="1-基座完成通信类和-spi-的定义">1. 基座完成通信类和 SPI 的定义</h3>
<p>在合并部署接入改造的基础上，需要完成通信类和 SPI 的定义。
通信类需要以 **独立 bundle **的方式存在，才能被模块引入。可参考以下方式：</p>
<ol>
<li>新建 bundle，定义接口类</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>public class ProductInfo {
</span></span><span style="display:flex;"><span>    private String  name;
</span></span><span style="display:flex;"><span>    private String  author;
</span></span><span style="display:flex;"><span>    private String  src;
</span></span><span style="display:flex;"><span>    private Integer orderCount;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ol start="2">
<li>定义 SPI</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">interface</span> <span style="color:#000">StrategyService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">strategy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getAppName</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="2-模块-1-引入通信类基座并实现基座-spi">2. 模块 1 <strong>引入通信类基座并实现基座 SPI</strong></h3>
<p>在上文合并部署模块 1 接入改造 demo 的基础上，引入通信类，然后定义 SPI 实现。</p>
<ol>
<li>引入通信类和对应 SPI 定义，只需要<strong>在 pom 里引入基座定义的通信 bundle</strong></li>
<li>定义 SPI 实现</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@Service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">StrategyServiceImpl</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">StrategyService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Autowired</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ApplicationContext</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">applicationContext</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Override</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">strategy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Override</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getAppName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">applicationContext</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getApplicationName</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><ol start="3">
<li>执行 <code>arkctl deploy</code> 构建部署，成功后用 <code>curl localhost:8080/${基座服务入口}/biz1/</code> 验证服务返回</li>
</ol>
<p><strong>biz1</strong> 传入是为了使基座根据不同的参数找到不同的 SPI 实现，执行不同的逻辑。传入的方式可以有很多种，这里用最简单方式——从 **path **里传入。</p>
<pre tabindex="0"><code>默认的 products 列表
</code></pre><h3 id="3-模块-2-引入通信类基座并实现基座-spi">3. 模块 2 <strong>引入通信类基座并实现基座 SPI</strong></h3>
<p>与模块 1 操作相同，需要注意执行 <code>arkctl deploy</code> 构建部署时，成功后 <code>curl localhost:8080/${基座服务入口}/biz2/</code> 验证服务返回。同理，**biz2 **传入是为了基座根据不同的参数，找到不同的 SPI 实现，执行不同逻辑。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@Service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">StrategyServiceImpl</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">StrategyService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Autowired</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ApplicationContext</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">applicationContext</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Override</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">strategy</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">ProductInfo</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Collections</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">sort</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">m</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">n</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">n</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getOrderCount</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">-</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">m</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getOrderCount</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">stream</span><span style="color:#000;font-weight:bold">().</span><span style="color:#c4a000">forEach</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">p</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">p</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">p</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#ce5c00;font-weight:bold">+</span><span style="color:#4e9a06">&#34;(&#34;</span><span style="color:#ce5c00;font-weight:bold">+</span><span style="color:#000">p</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getOrderCount</span><span style="color:#000;font-weight:bold">()</span><span style="color:#ce5c00;font-weight:bold">+</span><span style="color:#4e9a06">&#34;)&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">products</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Override</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getAppName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">applicationContext</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getApplicationName</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><pre tabindex="0"><code>更改排序后的 products 列表
</code></pre><p>基于上述操作，就可以继续进行上文中模块 <a href="https://sofaserverless.gitee.io/docs/tutorials/trial_step_by_step/"><strong>开发与验证</strong></a> 的操作了。整体流程丝滑易上手，欢迎试用！</p>
<h2 id="文档中的链接地址">文档中的链接地址</h2>
<ol>
<li>本实验工程样例地址：<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/web/tomcat">https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/web/tomcat</a></li>
<li><code>web-ark-plugin</code> 原理： <a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-multi-web-component-deploy/">https://www.sofastack.tech/projects/sofa-boot/sofa-ark-multi-web-component-deploy/</a></li>
<li>自动排包原理与配置文件下载：<a href="https://sofaserverless.gitee.io/docs/tutorials/module-development/module-slimming/#%E4%B8%80%E9%94%AE%E8%87%AA%E5%8A%A8%E7%98%A6%E8%BA%AB">https://sofaserverless.gitee.io/docs/tutorials/module-development/module-slimming/#%E4%B8%80%E9%94%AE%E8%87%AA%E5%8A%A8%E7%98%A6%E8%BA%AB</a></li>
<li>Arkctl 下载地址：<a href="https://github.com/sofastack/sofa-serverless/releases/tag/arkctl-release-0.1.0">https://github.com/sofastack/sofa-serverless/releases/tag/arkctl-release-0.1.0</a></li>
<li>本文档地址：<a href="https://sofaserverless.gitee.io/docs/tutorials/trial_step_by_step/">https://sofaserverless.gitee.io/docs/tutorials/trial_step_by_step/</a></li>
</ol>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-1338dd6d363fcbe1552c858a20719417">4 - 模块研发</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-bf65e93b734e75f456eb02447ae9f065">4.1 - 编码规范</h1>
    
	<h2 id="基础规范">基础规范</h2>
<ol>
<li>SOFAServerless 模块中官方验证并兼容的中间件客户端列表<a href="/docs/tutorials/module-operation/runtime-compatibility-list">详见此处</a>。基座中可以使用任意中间件客户端。</li>
<li>如果使用了模块热卸载能力，模块自定义的 Timer、ThreadPool 等需要在模块<strong>卸载时手动清理</strong>。您可以监听 Spring 的 <strong>ContextClosedEvent</strong> 事件，在事件处理函数中清理必要资源，也可以在 Spring XML 定义 Timer、ThreadPool 的地方指定它们的 <strong>destroy-method，<strong>在模块卸载时，Spring 会自动执行</strong> destroy-method</strong>。</li>
<li>基座启动时会部署所有模块，所以基座编码时，一定要向所有模块兼容，否则基座会发布失败。如果遇到无法绕过的不兼容变更（一般是在模块拆分过程中会有比较多的基座与模块不兼容变更），请参见<a href="/docs/tutorials/module-operation/incompatible-base-and-module-upgrade">基座与模块不兼容发布</a>。</li>
</ol>
<h2 id="知识点">知识点</h2>
<p><a href="../module-slimming">模块瘦身</a>  (重要)<br />
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-ark-jvm/">模块与模块、模块与基座通信</a>  (重要)<br />
<a href="../module-debug">模块测试</a>  (重要)<br />
<a href="../reuse-base-interceptor">模块复用基座拦截器</a><br />
<a href="../reuse-base-datasource">模块复用基座数据源</a><br />
<a href="/docs/introduction/architecture/class-delegation-principle">基座与模块间类委托加载原理介绍</a></p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-6e3cbd7799f1397ab7793638f56a6f1a">4.2 - 模块瘦身</h1>
    
	<h2 id="为什么要瘦身">为什么要瘦身</h2>
<p>为了让模块安装更快、内存消耗更小：</p>
<ul>
<li>提高模块安装的速度，减少模块包大小，减少启动依赖，控制模块安装耗时 &lt; 30秒，甚至 &lt; 5秒。</li>
<li>模块启动后 Spring 上下文中会创建很多对象，如果启用了模块热卸载，可能无法完全回收，安装次数过多会造成 Old 区、Metaspace 区开销大，触发频繁 FullGC，所有要控制单模块包大小 &lt; 5MB。<strong>这样不替换或重启基座也能热部署热卸载数百次。</strong></li>
</ul>
<h2 id="一键自动瘦身">一键自动瘦身</h2>
<h3 id="瘦身原则">瘦身原则</h3>
<p>构建 ark-biz jar 包的原则是，在保证模块功能的前提下，将框架、中间件等通用的包尽量放置到基座中，模块中复用基座的包，这样打出的 ark-biz jar 会更加轻量。在复杂应用中，为了更好的使用模块自动瘦身功能，需要在模块瘦身配置 (模块根目录/conf/ark/文件名.txt) 中，在样例给出的配置名单的基础上，按照既定格式，排除更多的通用依赖包。</p>
<h3 id="步骤一">步骤一</h3>
<p>在「模块项目根目录/conf/ark/文件名.txt」中（比如：my-module/conf/ark/rules.txt），按照如下格式配置需要下沉到基座的框架和中间件常用包。您也可以直接复制<a href="https://github.com/sofastack/sofa-serverless/blob/module-slimming/samples/springboot-samples/slimming/log4j2/biz1/conf/ark/rules.txt">默认的 rules.txt 文件内容</a>到您的项目中。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>excludeGroupIds=org.apache*
</span></span><span style="display:flex;"><span>excludeArtifactIds=commons-lang
</span></span></code></pre></div><h3 id="步骤二">步骤二</h3>
<p>在模块打包插件中，引入上述配置文件：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>    <span style="color:#8f5902;font-style:italic">&lt;!-- 插件1：打包插件为 sofa-ark biz 打包插件，打包成 ark biz jar --&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-ark-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>2.2.5<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;id&gt;</span>default-cli<span style="color:#204a87;font-weight:bold">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#204a87;font-weight:bold">&lt;goal&gt;</span>repackage<span style="color:#204a87;font-weight:bold">&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;skipArkExecutable&gt;</span>true<span style="color:#204a87;font-weight:bold">&lt;/skipArkExecutable&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;outputDirectory&gt;</span>./target<span style="color:#204a87;font-weight:bold">&lt;/outputDirectory&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;bizName&gt;</span>biz1<span style="color:#204a87;font-weight:bold">&lt;/bizName&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#8f5902;font-style:italic">&lt;!-- packExcludesConfig	模块瘦身配置，文件名自定义，和配置对应即可--&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#8f5902;font-style:italic">&lt;!--					配置文件位置：biz1/conf/ark/rules.txt--&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;packExcludesConfig&gt;</span>rules.txt<span style="color:#204a87;font-weight:bold">&lt;/packExcludesConfig&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;webContextPath&gt;</span>biz1<span style="color:#204a87;font-weight:bold">&lt;/webContextPath&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;declaredMode&gt;</span>true<span style="color:#204a87;font-weight:bold">&lt;/declaredMode&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#8f5902;font-style:italic">&lt;!--					打包、安装和发布 ark biz--&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#8f5902;font-style:italic">&lt;!--					静态合并部署需要配置--&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#8f5902;font-style:italic">&lt;!--					&lt;attach&gt;true&lt;/attach&gt;--&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span></code></pre></div><h3 id="步骤三">步骤三</h3>
<p>打包构建出模块 ark-biz jar 包即可，您可以明显看出瘦身后的 ark-biz jar 包大小差异。</p>
<p>您可<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/slimming">点击此处</a>查看完整模块瘦身样例工程。您也可以阅读下文继续了解模块的瘦身原理。</p>
<h2 id="基本原理">基本原理</h2>
<p>SOFAServerless 底层借助 SOFAArk 框架，实现了模块之间、模块和基座之间的相互隔离，以下两个核心逻辑对编码非常重要，需要深刻理解：</p>
<ol>
<li>基座有独立的类加载器和 Spring 上下文，模块也有<strong>独立的类加载器</strong>和** Spring 上下文**，相互之间 Spring 上下文都是<strong>隔离的</strong>。</li>
<li>模块启动时会初始化各种对象，会<strong>优先使用模块的类加载器</strong>去加载构建产物 FatJar 中的 class、resource 和 Jar 包，<strong>找不到的类会委托基座的类加载器</strong>去查找。</li>
</ol>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/jpeg/8276/1678275655551-75bf283f-3817-447a-84b2-7f6f7f773300.jpeg" alt=""></p>
<p>基于这套类委托的加载机制，让基座和模块共用的 class、resource 和 Jar 包<strong>通通下沉</strong>到基座中，可以让模块构建产物<strong>非常小</strong>，更重要的是还能让模块在运行中大量复用基座已有的 class、bean、service、IO 连接池、线程池等资源，从而模块消耗的内存<strong>非常少</strong>，启动也能<strong>非常快</strong>。<br />所谓模块瘦身，就是让基座已经有的 Jar 依赖务必在模块中剔除干净，在主 pom.xml 和 bootstrap/pom.xml 将共用的 Jar 包 <strong>scope 都声明为 provided</strong>，让其不参与打包构建。</p>
<h2 id="手动排包瘦身">手动排包瘦身</h2>
<p>模块运行时装载类时，会优先从自己的依赖里找，找不到的话再委托基座的 ClassLoader 去加载。<br />所以对于基座已经存在的依赖，在模块 pom 里将其 scope 设置成 provided，避免其参与模块打包。<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/8276/1678276103445-036d226e-4f88-40bc-937d-90fd4c60b83d.png#clientId=udf1ce5b3-f5a9-4&amp;from=paste&amp;height=521&amp;id=jFiln&amp;originHeight=1042&amp;originWidth=1848&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=957278&amp;status=done&amp;style=none&amp;taskId=u254c8709-de81-4175-bcf8-f1c4a26bc49&amp;title=&amp;width=924" alt="image.png"></p>
<p>如果要排除的依赖无法找到，可以利用 <strong>maven helper 插件</strong>找到其直接依赖。举个例子，图示中要排除的依赖为 spring-boot-autoconfigure，右边的直接依赖有 sofa-boot-alipay-runtime，ddcs-alipay-sofa-boot-starter等（只需要看 scope 为 compile 的依赖）：<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/191604/1691733668683-34a9d11f-3ca6-4b66-a4e3-22ade9413094.png#clientId=u05d65c58-49f7-4&amp;from=paste&amp;height=869&amp;id=u467da8b5&amp;originHeight=1738&amp;originWidth=2644&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=1043897&amp;status=done&amp;style=none&amp;taskId=u70530c01-d7a5-4ca9-875d-3785f59242b&amp;title=&amp;width=1322" alt="image.png"><br />确定自己代码 pom.xml 中有 ddcs-alipay-sofa-boot-starter，增加 exlcusions 来排除依赖：<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/191604/1691735644585-9201c203-b749-46e9-ab96-49ecc8090098.png#clientId=uda997d0f-c9aa-4&amp;from=paste&amp;height=244&amp;id=ub08bbabe&amp;originHeight=488&amp;originWidth=1476&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=85290&amp;status=done&amp;style=none&amp;taskId=u7f72a9d1-a1cd-422e-a50a-beafc4a9c4a&amp;title=&amp;width=738" alt="image.png"></p>
<h2 id="在-pom-中统一排包更彻底">在 pom 中统一排包（更彻底）</h2>
<p>有些依赖引入了过多的间接依赖，手动排查比较困难，此时可以通过通配符匹配，把那些中间件、基座的依赖全部剔除掉，如 org.apache.commons、org.springframework 等等，这种方式会把间接依赖都排除掉，相比使用 sofa-ark-maven-plugin 排包效率会更高：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;dependency&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.serverless.mymodule<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>mymodule-core<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;exclusions&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;exclusion&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>org.springframework<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>*<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;/exclusion&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;exclusion&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>org.apache.commons<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>*<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;/exclusion&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;exclusion&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>......<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>*<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;/exclusion&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/exclusions&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/dependency&gt;</span>
</span></span></code></pre></div><h2 id="在-sofa-ark-maven-plugin-中指定排包">在 sofa-ark-maven-plugin 中指定排包</h2>
<p>通过使用 **excludeGroupIds、excludeGroupIds **能够排除大量基座上已有的公共依赖：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-ark-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;id&gt;</span>default-cli<span style="color:#204a87;font-weight:bold">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                  <span style="color:#204a87;font-weight:bold">&lt;goal&gt;</span>repackage<span style="color:#204a87;font-weight:bold">&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>              <span style="color:#204a87;font-weight:bold">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;excludeGroupIds&gt;</span>io.netty,org.apache.commons,......<span style="color:#204a87;font-weight:bold">&lt;/excludeGroupIds&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;excludeArtifactIds&gt;</span>validation-api,fastjson,hessian,slf4j-api,junit,velocity,......<span style="color:#204a87;font-weight:bold">&lt;/excludeArtifactIds&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;outputDirectory&gt;</span>../../target<span style="color:#204a87;font-weight:bold">&lt;/outputDirectory&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;bizName&gt;</span>mymodule<span style="color:#204a87;font-weight:bold">&lt;/bizName&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;finalName&gt;</span>mymodule-${project.version}-${timestamp}<span style="color:#204a87;font-weight:bold">&lt;/finalName&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;bizVersion&gt;</span>${project.version}-${timestamp}<span style="color:#204a87;font-weight:bold">&lt;/bizVersion&gt;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&lt;webContextPath&gt;</span>/mymodule<span style="color:#204a87;font-weight:bold">&lt;/webContextPath&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span></code></pre></div><br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-66b2590d54145be7fd0f895684bc34ef">4.3 - 模块与模块、模块与基座通信</h1>
    
	<p>基座与模块之间、模块与模块之间存在 spring 上下文隔离，互相的 bean 不会冲突、不可见。然而很多应用场景比如中台模式、独立模块模式等存在基座调用模块、模块调用基座、模块与模块互相调用的场景。
当前支持3种方式调用，@AutowiredFromBiz, @AutowiredFromBase, SpringServiceFinder 方法调用，注意三个方式使用的情况不同。</p>
<h1 id="spring-环境">Spring 环境</h1>
<h2 id="基座调用模块">基座调用模块</h2>
<p>只能使用 SpringServiceFinder</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@RestController</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">SampleController</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@RequestMapping</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">method</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">RequestMethod</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">GET</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">hello</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">studentProvider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getModuleService</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">                </span><span style="color:#4e9a06">&#34;studentProvider&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">studentProvider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getModuleService</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">                </span><span style="color:#4e9a06">&#34;teacherProvider&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Map</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">String</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">listModuleServices</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">                </span><span style="color:#000">Provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">beanName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">keySet</span><span style="color:#000;font-weight:bold">())</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result2</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">beanName</span><span style="color:#000;font-weight:bold">).</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;hello to ark master biz&#34;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h2 id="模块调用基座">模块调用基座</h2>
<h3 id="方式一注解-autowiredfrombase">方式一：注解 @AutowiredFromBase</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@RestController</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">SampleController</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBase</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;sampleServiceImplNew&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SampleService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceImplNew</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBase</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;sampleServiceImpl&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SampleService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceImpl</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBase</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">SampleService</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceList</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBase</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Map</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">String</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SampleService</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceMap</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBase</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">AppService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">appService</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@RequestMapping</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">method</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">RequestMethod</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">GET</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">hello</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">sampleServiceImplNew</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">sampleServiceImpl</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">SampleService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceList</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">sampleService</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">beanName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">keySet</span><span style="color:#000;font-weight:bold">())</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">sampleServiceMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">beanName</span><span style="color:#000;font-weight:bold">).</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">appService</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAppName</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;hello to ark2 dynamic deploy&#34;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="方式二编程api-springservicefinder">方式二：编程API SpringServiceFinder</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@RestController</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">SampleController</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@RequestMapping</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">method</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">RequestMethod</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">GET</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">hello</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">SampleService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceImplFromFinder</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getBaseService</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;sampleServiceImpl&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SampleService</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceImplFromFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">System</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">out</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">println</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">result</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Map</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">String</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SampleService</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceMapFromFinder</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">listBaseServices</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">SampleService</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">beanName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceMapFromFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">keySet</span><span style="color:#000;font-weight:bold">())</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sampleServiceMapFromFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">beanName</span><span style="color:#000;font-weight:bold">).</span><span style="color:#c4a000">service</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">System</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">out</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">println</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">result1</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;hello to ark2 dynamic deploy&#34;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h2 id="模块调用模块">模块调用模块</h2>
<p>参考模块调用基座，注解使用 @AutowiredFromBiz 和 编程API支持 SpringServiceFinder。</p>
<h3 id="方式一注解-autowiredfrombiz">方式一：注解 @AutowiredFromBiz</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@RestController</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">SampleController</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBiz</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">bizName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">bizVersion</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;studentProvider&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">studentProvider</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBiz</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">bizName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;teacherProvider&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AutowiredFromBiz</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">bizName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">bizVersion</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">List</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">Provider</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providers</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@RequestMapping</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">method</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">RequestMethod</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">GET</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">hello</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provide</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">studentProvider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provide1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providers</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provide2</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;hello to ark2 dynamic deploy&#34;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="方式二编程api-springservicefinder-1">方式二：编程API SpringServiceFinder</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@RestController</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">SampleController</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@RequestMapping</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">method</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">RequestMethod</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">GET</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">hello</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Provider</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getModuleService</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;teacherProvider&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">teacherProvider1</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Map</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">String</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringServiceFinder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">listModuleServices</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.0.1-SNAPSHOT&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Provider</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">for</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">beanName</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">keySet</span><span style="color:#000;font-weight:bold">())</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">Result</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">result2</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">providerMap</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">beanName</span><span style="color:#000;font-weight:bold">).</span><span style="color:#c4a000">provide</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Param</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;hello to ark2 dynamic deploy&#34;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p><a href="https://github.com/sofastack/sofa-serverless/tree/master/samples">完整样例</a></p>
<h1 id="sofaboot-环境">SOFABoot 环境</h1>
<p><a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-ark-jvm/">请参考该文档</a></p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-e829d04a9debc230b4d695f03971b67b">4.4 - 模块本地开发</h1>
    
	<h2 id="arkctl-工具安装">Arkctl 工具安装</h2>
<p>Arkctl 模块安装主要提供自动打包和部署能力，自动打包调用 mvn 命令构建模块 jar包，自动部署调用 <a href="/docs/contribution-guidelines/arklet/architecture/">arklet</a> 提供的 api 接口进行部署。如果不想使用命令行工具，也可以直接使用 arklet 提供的 api 接口发起部署操作。</p>
<p>方法一：</p>
<ol>
<li>本地安装 go 环境，go 依赖版本在 1.21 以上。</li>
<li>执行 go install <code>todo 独立的 arkctl go 仓库</code> 命令，安装 arkctl 工具。</li>
</ol>
<p>方法二：</p>
<ol>
<li>在 [二进制列表](<a href="https://github.com/sofastack/sofa-serverless/releases/tag/arkctl-release-0.1.0">https://github.com/sofastack/sofa-serverless/releases/tag/arkctl-release-0.1.0</a> 中下载对应的二进制并加入到本地
path 中。</li>
</ol>
<h3 id="本地快速部署">本地快速部署</h3>
<p>你可以使用 arkctl 工具快速地进行模块的构建和部署，提高本地调试和研发效率。</p>
<h4 id="场景-1模块-jar-包构建--部署到本地运行的基座中">场景 1：模块 jar 包构建 + 部署到本地运行的基座中。</h4>
<p>准备：</p>
<ol>
<li>在本地启动一个基座。</li>
<li>打开一个模块项目仓库。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 需要在仓库的根目录下执行。</span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 比如，如果是 maven 项目，需要在根 pom.xml 所在的目录下执行。</span>
</span></span><span style="display:flex;"><span>arkctl deploy
</span></span></code></pre></div><p>命令执行完成后即部署成功，用户可以进行相关的模块功能调试验证。</p>
<h4 id="场景-2部署一个本地构建好的-jar-包到本地运行的基座中">场景 2：部署一个本地构建好的 jar 包到本地运行的基座中。</h4>
<p>准备：</p>
<ol>
<li>在本地启动一个基座。</li>
<li>准备一个构建好的 jar 包。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>arkctl deploy /path/to/your/pre/built/bundle-biz.jar
</span></span></code></pre></div><p>命令执行完成后即部署成功，用户可以进行相关的模块功能调试验证。</p>
<h4 id="场景-3-模块-jar-包构建--部署到远程运行的-k8s-基座中">场景 3: 模块 jar 包构建 + 部署到远程运行的 k8s 基座中。</h4>
<p>准备:</p>
<ol>
<li>在远程已经运行起来的基座 pod。</li>
<li>打开一个模块项目仓库。</li>
<li>本地需要有具备 exec 权限的 k8s 证书以及 kubectl 命令行工具。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 需要在仓库的根目录下执行。</span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 比如，如果是 maven 项目，需要在根 pom.xml 所在的目录下执行。</span>
</span></span><span style="display:flex;"><span>arkctl deploy --pod <span style="color:#ce5c00;font-weight:bold">{</span>namespace<span style="color:#ce5c00;font-weight:bold">}</span>/<span style="color:#ce5c00;font-weight:bold">{</span>podName<span style="color:#ce5c00;font-weight:bold">}</span>
</span></span></code></pre></div><p>命令执行完成后即部署成功，用户可以进行相关的模块功能调试验证。</p>
<h4 id="场景-4-在多模块的-maven-项目中在-root-构建并部署子模块的-jar-包">场景 4: 在多模块的 Maven 项目中，在 Root 构建并部署子模块的 jar 包。</h4>
<p>准备：</p>
<ol>
<li>在本地启动一个基座。</li>
<li>打开一个多模块 Maven 项目仓库。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 需要在仓库的根目录下执行。</span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"># 比如，如果是 maven 项目，需要在根 pom.xml 所在的目录下执行。</span>
</span></span><span style="display:flex;"><span>arkctl deploy --sub ./path/to/your/sub/module
</span></span></code></pre></div><p>命令执行完成后即部署成功，用户可以进行相关的模块功能调试验证。</p>
<h4 id="场景-5-查询当前基座中已经部署的模块">场景 5: 查询当前基座中已经部署的模块。</h4>
<p>准备：</p>
<ol>
<li>在本地启动一个基座。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>arkctl status
</span></span></code></pre></div><h4 id="场景-6-查询远程-k8s-环境基座中已经部署的模块">场景 6: 查询远程 k8s 环境基座中已经部署的模块。</h4>
<p>准备：</p>
<ol>
<li>在远程 k8s 环境启动一个基座。</li>
<li>确保本地有 kube 证书以及有关权限。</li>
</ol>
<p>执行命令：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>arkctl status --pod <span style="color:#ce5c00;font-weight:bold">{</span>namespace<span style="color:#ce5c00;font-weight:bold">}</span>/<span style="color:#ce5c00;font-weight:bold">{</span>name<span style="color:#ce5c00;font-weight:bold">}</span>
</span></span></code></pre></div>
</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-28a800d400556ead949da2297e04f900">4.5 - 模块测试</h1>
    
	<h2 id="本地调试">本地调试</h2>
<p>您可以在本地或远程先启动基座，然后使用客户端 Arklet 暴露的 HTTP 接口在本地或远程部署模块，并且可以给模块代码打断点实现模块的本地或远程 Debug。<br />Arklet HTTP 接口主要提供了以下能力：</p>
<ol>
<li>部署和卸载模块。</li>
<li>查询所有已部署的模块信息。</li>
<li>查询各项系统和业务指标。</li>
</ol>
<h3 id="部署模块">部署模块</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -X POST -H <span style="color:#4e9a06">&#34;Content-Type: application/json&#34;</span> http://127.0.0.1:1238/installBiz 
</span></span></code></pre></div><p>请求体样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8f5902;font-style:italic">// local path should start with file://, alse support remote url which can be downloaded
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>    <span style="color:#204a87;font-weight:bold">&#34;bizUrl&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;file:///Users/jaimezhang/workspace/github/sofa-ark-dynamic-guides/dynamic-provider/target/dynamic-provider-1.0.0-ark-biz.jar&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>部署成功返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizInfos&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;declaredMode&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;identity&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider:1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;io.sofastack.dynamic.provider.ProviderApplication&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;priority&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#0000cf;font-weight:bold">100</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;provider&#34;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">],</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Install Biz: dynamic-provider:1.0.0 success, cost: 1092 ms, started at: 16:07:47,769&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>部署失败返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;FAILED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;REPEAT_BIZ&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Biz: dynamic-provider:1.0.0 has been installed or registered.&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="卸载模块">卸载模块</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -X POST -H <span style="color:#4e9a06">&#34;Content-Type: application/json&#34;</span> http://127.0.0.1:1238/uninstallBiz 
</span></span></code></pre></div><p>请求体样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>卸载成功返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>卸载失败返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;FAILED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;NOT_FOUND_BIZ&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Uninstall biz: test:1.0.0 not found.&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="查询模块">查询模块</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -X POST -H <span style="color:#4e9a06">&#34;Content-Type: application/json&#34;</span> http://127.0.0.1:1238/queryAllBiz 
</span></span></code></pre></div><p>请求体样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{}</span>
</span></span></code></pre></div><p>返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;io.sofastack.dynamic.provider.ProviderApplication&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;provider&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;stock-mng&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;embed main&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="获取帮助">获取帮助</h3>
<p>Arklet 暴露的所有对外 HTTP 接口，可以查看 Arklet 接口帮助：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -X POST -H <span style="color:#4e9a06">&#34;Content-Type: application/json&#34;</span> http://127.0.0.1:1238/help 
</span></span></code></pre></div><p>请求体样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{}</span>
</span></span></code></pre></div><p>返回结果样例：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;query all ark biz(including master biz)&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;queryAllBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;list all supported commands&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;help&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;uninstall one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;uninstallBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;switch one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;switchBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;install one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;installBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="本地构建如何不改变模块版本号">本地构建如何不改变模块版本号</h2>
<p>添加以下 maven profile，本地构建模块使用命令 mvn clean package -Plocal</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;profile&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;id&gt;</span>local<span style="color:#204a87;font-weight:bold">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;build&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;plugins&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-ark-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#204a87;font-weight:bold">&lt;finalName&gt;</span>${project.artifactId}-${project.version}<span style="color:#204a87;font-weight:bold">&lt;/finalName&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#204a87;font-weight:bold">&lt;bizVersion&gt;</span>${project.version}<span style="color:#204a87;font-weight:bold">&lt;/bizVersion&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/plugins&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/build&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/profile&gt;</span>
</span></span></code></pre></div><h2 id="单元测试">单元测试</h2>
<p>模块里支持使用标准 JUnit4 和 TestNG 编写和执行单元测试。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-037484c6b7708a4128ecdd19d8578aaa">4.6 - 复用基座拦截器</h1>
    
	<h1 id="诉求">诉求</h1>
<p>基座中会定义很多 Aspect 切面（Spring 拦截器），你可能希望复用到模块中，但是模块和基座的 Spring 上下文是隔离的，就导致 Aspect 切面不会在模块中生效。<br/><br/></p>
<h1 id="解法">解法</h1>
<p>为原有的切面类创建一个代理对象，让模块能调用到这个代理对象，然后模块通过 AutoConfiguration 注解初始化出这个代理对象。完整步骤和示例代码如下：</p>
<h3 id="步骤-1">步骤 1：</h3>
<p>基座代码定义一个接口，定义切面的执行方法。这个接口需要对模块可见（在模块里引用相关依赖）：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">interface</span> <span style="color:#000">AnnotionService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000">Object</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">doAround</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ProceedingJoinPoint</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">joinPoint</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">throws</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Throwable</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="步骤-2">步骤 2：</h3>
<p>在基座中编写切面的具体实现，这个实现类需要加上 @SofaService 注解（SOFABoot）或者 @SpringService 注解（SpringBoot，<em>建设中</em>）：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@Service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@SofaService</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">uniqueId</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;facadeAroundHandler&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">FacadeAroundHandler</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">AnnotionService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">final</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">static</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Logger</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">LOG</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">LoggerConst</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">MY_LOGGER</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Object</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">doAround</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ProceedingJoinPoint</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">joinPoint</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">throws</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Throwable</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">info</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;开始执行&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">joinPoint</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">proceed</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">log</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">info</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;执行完成&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="步骤-3">步骤 3：</h3>
<p>在模块里使用 @Aspect 注解实现一个 Aspect，SOFABoot 通过 @SofaReference 注入基座上的 FacadeAroundHandler。<br /><strong>注意</strong>：这里不要声明成一个 Bean，不要加 @Component 或者 @Service 注解，主需要 @Aspect 注解。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//注意，这里不必申明成一个bean，不要加@Component或者@Service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@Aspect</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">FacadeAroundAspect</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@SofaReference</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">uniqueId</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;facadeAroundHandler&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">AnnotionService</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">facadeAroundHandler</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Pointcut</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;@annotation(com.alipay.linglongmng.presentation.mvc.interceptor.FacadeAround)&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">facadeAroundPointcut</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Around</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;facadeAroundPointcut()&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Object</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">doAround</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ProceedingJoinPoint</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">joinPoint</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">throws</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Throwable</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">facadeAroundHandler</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">doAround</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">joinPoint</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="步骤-4">步骤 4：</h3>
<p>使用 @Configuration 注解写个 Configuration 配置类，把模块需要的 aspectj 对象都声明成 Spring Bean。<br /><strong>注意</strong>：这个 Configuration 类需要对模块可见，相关 Spring Jar 依赖需要以 <scope>provided</scope> 方式引进来。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">MngAspectConfiguration</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">FacadeAroundAspect</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">facadeAroundAspect</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">FacadeAroundAspect</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">EnvRouteAspect</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">envRouteAspect</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">EnvRouteAspect</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">FacadeAroundAspect</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">facadeAroundAspect</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">FacadeAroundAspect</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h3 id="步骤-5">步骤 5：</h3>
<p>模块代码中显示的依赖步骤 4 创建的 Configuration 配置类 MngAspectConfiguration。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@SpringBootApplication</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@ImportResource</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;classpath*:META-INF/spring/*.xml&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@ImportAutoConfiguration</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#000">MngAspectConfiguration</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">})</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">ModuleBootstrapApplication</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">static</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">main</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">String</span><span style="color:#ce5c00;font-weight:bold">[]</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">args</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">SpringApplicationBuilder</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">builder</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SpringApplicationBuilder</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ModuleBootstrapApplication</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">class</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        	</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">web</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">WebApplicationType</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">NONE</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">builder</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">build</span><span style="color:#000;font-weight:bold">().</span><span style="color:#c4a000">run</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">args</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-06ace3863ce3b10117de52a241f0d9e0">4.7 - 复用基座数据源</h1>
    
	<h2 id="建议">建议</h2>
<p>强烈建议使用本文档方式，在模块中尽可能<strong>复用基座数据源</strong>，否则模块反复部署就会反复创建、消耗数据源连接，导致模块发布运维会变慢，同时也会额外消耗内存。<br/></p>
<h2 id="springboot-解法">SpringBoot 解法</h2>
<p>在模块的代码中写个 MybatisConfig 类即可，这样事务模板都是复用基座的，只有 Mybatis 的 SqlSessionFactoryBean 需要新创建。<br /> 参考 demo：/sofa-serverless/samples/springboot-samples/db/mybatis/biz1</p>
<p>通过<code>SpringBeanFinder.getBaseBean</code>获取到基座的 Bean 对象，然后注册成模块的 Bean：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@MapperScan</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">basePackages</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;com.alipay.sofa.biz1.mapper&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sqlSessionFactoryRef</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;mysqlSqlFactory&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@EnableTransactionManagement</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">MybatisConfig</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#8f5902;font-style:italic">//tips:不要初始化一个基座的DataSource，当模块被卸载的是，基座数据源会被销毁，transactionManager，transactionTemplate，mysqlSqlFactory被销毁没有问题</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;transactionManager&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">PlatformTransactionManager</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">platformTransactionManager</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">PlatformTransactionManager</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getBaseBean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;transactionManager&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;transactionTemplate&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">TransactionTemplate</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">transactionTemplate</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">TransactionTemplate</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getBaseBean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;transactionTemplate&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;mysqlSqlFactory&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">throws</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">IOException</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">//数据源不能申明成模块spring上下文中的bean，因为模块卸载时会触发close方法</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">DataSource</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dataSource</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">DataSource</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">getBaseBean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;dataSource&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setDataSource</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">dataSource</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setMapperLocations</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">PathMatchingResourcePatternResolver</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">                </span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getResources</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;classpath:mappers/*.xml&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h2 id="sofaboot-解法">SOFABoot 解法</h2>
<p>如果 SOFABoot 基座没有开启多 bundle（Package 里没有 MANIFEST.MF 文件），则解法和上文 SpringBoot 完全一致。<br />如果有 MANIFEST.MF 文件，需要调用<code>BaseAppUtils.getBeanOfBundle</code>获取基座的 Bean，其中<strong>BASE_DAL_BUNDLE_NAME</strong> 为 MANIFEST.MF 里面的<code>Module-Name</code>：<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2022/png/38696/1661758587977-7a499d0d-d5ca-4a68-9925-fa7258679d9b.png#clientId=ue6b6f4dc-5527-4&amp;errorMessage=unknown%20error&amp;from=paste&amp;height=458&amp;id=u531b3c3e&amp;originHeight=916&amp;originWidth=2042&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;size=383535&amp;status=error&amp;style=none&amp;taskId=ua403e261-49af-4d10-99e6-12edf669677&amp;title=&amp;width=1021" alt="image.png"></p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@Configuration</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@MapperScan</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">basePackages</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;com.alipay.serverless.dal.dao&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">sqlSessionFactoryRef</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;mysqlSqlFactory&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#5c35cc;font-weight:bold">@EnableTransactionManagement</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">MybatisConfig</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#8f5902;font-style:italic">// 注意：不要初始化一个基座的 DataSource，会导致模块被热卸载的时候，基座的数据源被销毁，不符合预期。</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#8f5902;font-style:italic">// 但是 transactionManager，transactionTemplate，mysqlSqlFactory 这些资源被销毁没有问题</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">static</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">final</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">String</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">BASE_DAL_BUNDLE_NAME</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;com.alipay.serverless.dal&#34;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;transactionManager&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">PlatformTransactionManager</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">platformTransactionManager</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">PlatformTransactionManager</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">BaseAppUtils</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getBeanOfBundle</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;transactionManager&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#000">BASE_DAL_BUNDLE_NAME</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;transactionTemplate&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">TransactionTemplate</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">transactionTemplate</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">TransactionTemplate</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">BaseAppUtils</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getBeanOfBundle</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;transactionTemplate&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#000">BASE_DAL_BUNDLE_NAME</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">name</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;mysqlSqlFactory&#34;</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">throws</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">IOException</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">//数据源不能申明成模块spring上下文中的bean，因为模块卸载时会触发close方法</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">ZdalDataSource</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dataSource</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ZdalDataSource</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">BaseAppUtils</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getBeanOfBundle</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;dataSource&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#000">BASE_DAL_BUNDLE_NAME</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SqlSessionFactoryBean</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setDataSource</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">dataSource</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setMapperLocations</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">PathMatchingResourcePatternResolver</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">                </span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getResources</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;classpath:mapper/*.xml&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">mysqlSqlFactory</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-4a763f2560193bc6f6a4c64874383f22">4.8 - 静态合并部署</h1>
    
	<h2 id="介绍">介绍</h2>
<p>SOFAArk 提供了静态合并部署能力，在开发阶段，应用可以将其他应用构建成的 <strong>Biz 包（模块应用)</strong>，并被最终的 <strong>Base 包（基座应用）</strong> 加载。
用户可以把 Biz 包统一放置在某个目录中，然后通过启动参数告知基座扫描这个目录，以此完成静态合并部署（详情见下描述）。如此，开发不需要考虑相互之间依赖冲突问题，Biz 之间则通过 @SofaService 和 @SofaReference 发布/引用 JVM 服务（<em>SOFABoot，SpringBoot 还在建设中</em>
）进行交互。</p>
<h2 id="步骤-1模块应用打包成-ark-biz">步骤 1：模块应用打包成 Ark Biz</h2>
<p>如果开发者希望自己应用的 Ark Biz 包能够被其他应用直接当成 Jar 包依赖，进而运行在同一个 SOFAArk 容器之上，那么就需要打包发布 Ark Biz
包，详见 <a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-ark-biz/">Ark Biz 介绍</a>。 Ark Biz 包使用
Maven 插件 sofa-ark-maven-plugin 打包生成。</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;build&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.alipay.sofa<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>sofa-ark-maven-plugin<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>${sofa.ark.version}<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;id&gt;</span>default-cli<span style="color:#204a87;font-weight:bold">&lt;/id&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#204a87;font-weight:bold">&lt;goal&gt;</span>repackage<span style="color:#204a87;font-weight:bold">&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/build&gt;</span>
</span></span></code></pre></div><h2 id="步骤-2将上述-jar-包移动到指定目录">步骤 2：将上述 jar 包移动到指定目录。</h2>
<p>把需要部署的 biz jar 都移动到指定目录，如：/home/sofa-ark/biz/</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>mv /path/to/your/biz/jar /home/sofa-ark/biz/
</span></span></code></pre></div><h2 id="步骤-3启动基座并通过--d-参指定-biz-目录">步骤 3：启动基座，并通过 -D 参指定 biz 目录</h2>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>java -jar -Dcom.alipay.sofa.ark.static.biz.dir<span style="color:#ce5c00;font-weight:bold">=</span>/home/sofa-ark/biz/ sofa-ark-base.jar
</span></span></code></pre></div><h2 id="步骤-4验证-ark-biz模块启动">步骤 4：验证 Ark Biz（模块）启动</h2>
<p>在基座启动成功后，可以通过 telnet 启动 SOFAArk 客户端交互界面：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>telnet localhost <span style="color:#0000cf;font-weight:bold">1234</span>
</span></span></code></pre></div><p>然后执行如下命令查看模块列表：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>biz -a
</span></span></code></pre></div><p>此时应当可以看到 Master Biz（基座）和所有静态合并部署的 Ark Biz（模块）。<br/>
上述操作可以通过 <a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/web/tomcat/README.md#%E5%AE%9E%E9%AA%8C%E5%86%85%E5%AE%B9(%E9%9D%99%E6%80%81%E5%90%88%E5%B9%B6%E9%83%A8%E7%BD%B2)">SOFAArk 静态合并部署样例</a>
体验。<br/></p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-dbe415e386e1bcdf1f3e7a62a91e6eb6">4.9 - 模块中官方支持的中间件客户端</h1>
    
	<p>在 SOFAServerless 模块中，官方目前支持并兼容常见的中间件客户端。<br /><strong>注意</strong>，这里 “<strong>已经支持</strong>” 需要在基座 POM
中引入相关客户端依赖（<strong>强烈建议使用 SpringBoot Starter 方式引入相关依赖</strong>），同时在模块 POM 中也引入相关依赖并设置 *
<em><scope>provided</scope></em>* 将依赖委托给基座加载。</p>
<br/>
<table>
<thead>
<tr>
<th>中间件客户端</th>
<th>版本号</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>JDK</td>
<td>8.x<br />17.x</td>
<td><em><strong>已经支持</strong></em><br /></td>
</tr>
<tr>
<td>SpringBoot</td>
<td>&gt;= 2.3.0  或  3.x</td>
<td><em><strong>已经支持</strong></em><br />JDK17 + SpringBoot3.x 基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot3-samples/web/tomcat">参见此处</a></td>
</tr>
<tr>
<td>SpringBoot Cloud</td>
<td>&gt;= 2.7.x</td>
<td><em><strong>已经支持</strong></em><br/> 基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/springcloud/">参见此处</a></td>
</tr>
<tr>
<td>SOFABoot</td>
<td>&gt;= 3.9.0  或  4.x</td>
<td><em><strong>已经支持</strong></em><br /></td>
</tr>
<tr>
<td>JMX</td>
<td>N/A</td>
<td><em><strong>已经支持</strong></em><br /> 需要给基座加  <em>-Dspring.jmx.default-domain=${spring.application.name}</em>  启动参数 <br /></td>
</tr>
<tr>
<td>log4j2</td>
<td>任意</td>
<td><em><strong>已经支持</strong></em>。在基座和模块引入 log4j2，并额外引入依赖：<br/>&lt;dependency&gt;<br/>  &lt;groupId&gt;com.alipay.sofa.serverless&lt;/groupId&gt;<br/>  &lt;artifactId&gt;sofa-serverless-adapter-log4j2&lt;/artifactId&gt;<br/>  &lt;version&gt;${最新版 SOFAServerless 版本}&lt;/version&gt;<br/>  &lt;scope&gt;provided&lt;/scope&gt; &lt;!&ndash; 模块需要 provided &ndash;&gt;<br/>  &lt;/dependency&gt;<br/>基座和模块完整使用样例<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/logging/README.md">参见此处</a></td>
</tr>
<tr>
<td>slf4j-api</td>
<td>1.x 且 &gt;= 1.7</td>
<td><em><strong>已经支持</strong></em><br /></td>
</tr>
<tr>
<td>tomcat</td>
<td>7.x、8.x、9.x、10.x <br />及以上均可</td>
<td><em><strong>已经支持</strong></em><br /> 基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/web/tomcat">参见此处</a></td>
</tr>
<tr>
<td>netty</td>
<td>4.x</td>
<td><em><strong>已经支持</strong></em><br /> 基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/web/webflux">参见此处</a></td>
</tr>
<tr>
<td>sofarpc</td>
<td>&gt;= 5.8.6</td>
<td><em><strong>已经支持</strong></em><br /></td>
</tr>
<tr>
<td>dubbo</td>
<td>3.x</td>
<td><em><strong>已经支持</strong></em><br/>基座和模块完整使用样例及注意事项可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/dubbo-samples/rpc/grpc">参见此处</a></td>
</tr>
<tr>
<td>grpc</td>
<td>1.x 且 &gt;= 1.42</td>
<td><em><strong>已经支持</strong></em><br/>基座和模块完整使用样例及注意事项可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/dubbo-samples/rpc/grpc">参见此处</a></td>
</tr>
<tr>
<td>protobuf-java</td>
<td>3.x 且 &gt;= 3.17</td>
<td><em><strong>已经支持</strong></em><br/>基座和模块完整使用样例及注意事项可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/dubbo-samples/rpc/grpc">参见此处</a></td>
</tr>
<tr>
<td>apollo</td>
<td>1.x 且 &gt;= 1.6.0</td>
<td><em><strong>已经支持</strong></em><br/>基座和模块完整使用样例及注意事项可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/config/apollo">参见此处</a></td>
</tr>
<tr>
<td>nacos</td>
<td>2.1.x</td>
<td><em><strong>已经支持</strong></em><br/>     基座和模块完整使用样例及注意事项可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/config/nacos">参见此处</a></td>
</tr>
<tr>
<td>kafka-client</td>
<td>&gt;= 2.8.0  或<br />&gt;= 3.4.0</td>
<td><em><strong>已经支持</strong></em><br />基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/logging/README.md">参见此处</a></td>
</tr>
<tr>
<td>rocketmq</td>
<td>4.x 且 &gt;= 4.3.0</td>
<td><em><strong>已经支持</strong></em> <br/>基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/msg/rocketmq/README.md">参见此处</a></td>
</tr>
<tr>
<td>jedis</td>
<td>3.x</td>
<td><em><strong>已经支持</strong></em><br />基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/redis">参见此处</a></td>
</tr>
<tr>
<td>xxl-job</td>
<td>2.x 且 &gt;= 2.1.0</td>
<td><em><strong>已经支持</strong></em><br />需要在模块里声明为 compile 依赖独立使用 <br/></td>
</tr>
<tr>
<td>mybatis</td>
<td>&gt;= 2.2.2  或<br />&gt;= 3.5.12</td>
<td><em><strong>已经支持</strong></em><br />基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/db/mybatis/README.md">参见此处</a></td>
</tr>
<tr>
<td>druid</td>
<td>1.x</td>
<td><em><strong>已经支持</strong></em><br />基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/db/mybatis/README.md">参见此处</a></td>
</tr>
<tr>
<td>mysql-connector-java</td>
<td>8.x</td>
<td><em><strong>已经支持</strong></em><br />基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/db/mybatis/README.md">参见此处</a></td>
</tr>
<tr>
<td>postgresql</td>
<td>42.x 且 &gt;= 42.3.8</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>mongodb</td>
<td>4.6.1</td>
<td><em><strong>已经支持</strong></em> <br/>     基座和模块完整使用样例可<a href="https://github.com/sofastack/sofa-serverless/blob/master/samples/springboot-samples/db/mongo/README.md">参见此处</a></td>
</tr>
<tr>
<td>hibernate</td>
<td>5.x 且 &gt;= 5.6.15</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>j2cache</td>
<td>任意</td>
<td><em><strong>已经支持</strong></em><br />需要在模块里声明为 compile 依赖独立使用 <br/></td>
</tr>
<tr>
<td>opentracing</td>
<td>0.x 且 &gt;= 0.32.0</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>elasticsearch</td>
<td>7.x 且 &gt;= 7.6.2</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>jaspyt</td>
<td>1.x 且 &gt;= 1.9.3</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>OKHttp</td>
<td>-</td>
<td><em><strong>已经支持</strong></em><br/>需要放在基座里，请使用<a href="https://github.com/sofastack/sofa-serverless/blob/master/docs/content/zh-cn/docs/tutorials/module-development/module-slimming.md">模块自动瘦身能力</a></td>
</tr>
<tr>
<td>io.kubernetes:client</td>
<td>10.x 且 &gt;= 10.0.0</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>net.java.dev.jna</td>
<td>5.x 且 &gt;= 5.12.1</td>
<td><em><strong>已经支持</strong></em></td>
</tr>
<tr>
<td>prometheus</td>
<td>-</td>
<td>待验证支持</td>
</tr>
</tbody>
</table>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-4c134980130d1dc3c830b9224a754361">4.10 - SOFAArk 关键用户文档</h1>
    
	<p><b><a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-biz-lifecycle/">模块生命周期</a></b><br /><br />
<b><a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-ark-event/">Ark 事件机制</a></b><br /><br />
<b><a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-ark-log/">Ark 自身日志</a></b><br /><br /></p>
<br/>
<br/>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-307f45cbc34bd56c2422e01b460303bb">5 - 模块运维</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-f274515d3bf16798aa419325f53c707a">5.1 - 模块上线与下线</h1>
    
	<h2 id="模块上线">模块上线</h2>
<p>在 K8S 集群中创建一个 ModuleDeployment CR 资源即可完成模块上线，例如：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace
</span></span></code></pre></div><p>其中 <em>deployment_v1alpha1_moduledeployment.yaml</em> 替换成您的 ModuleDeployment 定义 yaml 文件，<em>yournamespace</em> 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serverless.alipay.com/v1alpha1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ModuleDeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/instance</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/part-of</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/managed-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">kustomize</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/created-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">baseDeploymentName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dynamic-stock-deployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">module</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;1.0.2&#39;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">url</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">replicas</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">operationStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#8f5902;font-style:italic"># 此处可自定义发布运维策略</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">upgradePolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">installThenUninstall</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">needConfirm</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">useBeta</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">batchCount</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">schedulingStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># 此处可自定义调度策略</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">schedulingPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Scatter</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p>ModuleDeployment 所有字段可参考 <a href="/docs/contribution-guidelines/module-controller/crd-definition">ModuleDeployment CRD 字段解释</a>。<br />如果要自定义模块发布运维策略（比如分组、Beta、暂停等）可配置 operationStrategy 和 schedulingStrategy，具体可参考<a href="../operation-and-scheduling-strategy">模块发布运维策略</a>。<br />样例演示的是使用 kubectl 方式，直接调用 K8S APIServer 创建 ModuleDeployment CR 一样能实现模块分组上线。</p>
<h2 id="模块下线">模块下线</h2>
<p>在 K8S 集群中删除一个 ModuleDeployment CR 资源即可完成模块下线，例如：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl delete yourmoduledeployment --namespace yournamespace
</span></span></code></pre></div><p>其中 <em>yourmoduledeployment</em> 替换成您的 ModuleDeployment 名字（ModuleDeployment 的 metadata name），<em>yournamespace</em> 替换成您的 namespace。<br />如果要自定义模块发布运维策略（比如分组、Beta、暂停等）可配置 operationStrategy 和 schedulingStrategy，具体可参考<a href="../operation-and-scheduling-strategy">模块发布运维策略</a>。<br />样例演示的是使用 kubectl 方式，直接调用 K8S APIServer 删除 ModuleDeployment CR 一样能实现模块分组下线。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-7b5bd50a9b9adfe3d8e27a3a4117e738">5.2 - 模块发布</h1>
    
	<h2 id="模块发布">模块发布</h2>
<p>修改 ModuleDeployment.spec.template.spec.module.version 字段和 ModuleDeployment.spec.template.spec.module.url（可选）字段并重新 apply，即可实现新版本模块的分组发布，例如：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace
</span></span></code></pre></div><p>其中 <em>deployment_v1alpha1_moduledeployment.yaml</em> 替换成您的 ModuleDeployment 定义 yaml 文件，<em>yournamespace</em> 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serverless.alipay.com/v1alpha1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ModuleDeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/instance</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/part-of</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/managed-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">kustomize</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/created-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">baseDeploymentName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dynamic-stock-deployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">module</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;2.0.0&#39;</span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#8f5902;font-style:italic"># 注意：这里将 version 字段从 1.0.2 修改为了 2.0.0 即可实现模块新版本分组发布</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic"># 注意：url 字段可以修改为新的 jar 包地址，也可以不用修改</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">url</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">replicas</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">operationStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">upgradePolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">install_then_uninstall</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">needConfirm</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">grayTimeBetweenBatchSeconds</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">useBeta</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">batchCount</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">schedulingStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">schedulingPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">scatter</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p>如果要自定义模块发布运维策略可配置 operationStrategy，具体可参考<a href="/docs/contribution-guidelines/module-controller/crd-definition">模块发布运维策略</a>。<br />样例演示的是使用 kubectl 方式，直接调用 K8S APIServer 修改 ModuleDeployment CR 一样能实现分组发布。</p>
<h2 id="模块回滚">模块回滚</h2>
<p>重新修改 ModuleDeployment.spec.template.spec.module.version 字段和 ModuleDeployment.spec.template.spec.module.url（可选）字段并重新 apply，即可实现模块的分组回滚发布。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-03f7fcbe7eb355b82c98153891be1e48">5.3 - 基座和模块不兼容发布</h1>
    
	<h2 id="步骤--1">步骤  1</h2>
<p>修改基座代码和模块代码，然后将基座构建为新版本的镜像，将模块构建为新版本的代码包（Java 就是 Jar 包）。</p>
<h2 id="步骤--2">步骤  2</h2>
<p>修改模块对应的 ModuleDeployment.spec.template.spec.module.url 为新的模块代码包地址。</p>
<h2 id="步骤--3">步骤  3</h2>
<p>使用 K8S Deployment 发布基座到新版本镜像（会触发基座容器的替换或重启），基座容器启动时会拉取 ModuleDeployment 上最新的模块代码包地址，从而实现了基座与模块的不兼容变更（即同时发布）。<br/></p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-ac1464ebc2e0083dd90ccb0c00118fca">5.4 - 模块扩缩容与替换</h1>
    
	<h2 id="模块扩缩容">模块扩缩容</h2>
<p>修改 ModuleDeployment CR 的 replicas 字段并重新 apply，即可实现模块扩缩容，例如：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace
</span></span></code></pre></div><p>其中 <em>deployment_v1alpha1_moduledeployment.yaml</em> 替换成您的 ModuleDeployment 定义 yaml 文件，<em>yournamespace</em> 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serverless.alipay.com/v1alpha1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ModuleDeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/instance</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/part-of</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/managed-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">kustomize</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/created-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">baseDeploymentName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dynamic-stock-deployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">module</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;1.0.2&#39;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">url</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">replicas</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#8f5902;font-style:italic"># 注意：在此处修改模块实例 Module 副本数，实现扩缩容</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">operationStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">upgradePolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">installThenUninstall</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">needConfirm</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">useBeta</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">batchCount</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">schedulingStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># 此处可自定义调度策略</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">schedulingPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Scatter  </span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p>如果要自定义模块发布运维策略可配置 operationStrategy 和 schedulingStrategy，具体可参考<a href="../operation-and-scheduling-strategy">模块发布运维策略</a>。<br />样例演示的是使用 kubectl 方式，直接调用 K8S APIServer 修改 ModuleDeployment CR 一样能实现扩缩容。</p>
<h2 id="模块替换">模块替换</h2>
<p>在 K8S 集群中删除一个 Module CR 资源即可完成模块替换，例如：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl delete yourmodule --namespace yournamespace
</span></span></code></pre></div><p>其中 <em>yourmodule</em> 替换成您的 Module CR 实体名字（Module 的 metadata name），<em>yournamespace</em> 替换成您的 namespace。<br />样例演示的是使用 kubectl 方式，直接调用 K8S APIServer 删除 Module CR 一样能实现模块替换。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-7011e375d7565bd7cea7f9347f8e8c9e">5.5 - 模块发布运维策略</h1>
    
	<h2 id="运维策略">运维策略</h2>
<p>为了实现生产环境的无损变更，模块发布运维提供了安全可靠的变更能力，用户可以在 ModuleDeployment CR spec 的 operationStrategy 中，配置发布运维的变更策略。operationStrategy 内具体字段解释如下：</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>字段解释</th>
<th>取值范围</th>
<th>取值解释</th>
</tr>
</thead>
<tbody>
<tr>
<td>batchCount</td>
<td>分批发布运维批次数</td>
<td>1 - N</td>
<td>分 1 - N 批次发布运维模块</td>
</tr>
<tr>
<td>useBeta</td>
<td>是否启用 beta 分组发布。启用 beta 分组发布会让第一批次只有一个 IP 做灰度，剩下的 IP 再划分成 (batchCount - 1) 批</td>
<td>true 或 false</td>
<td>true 表示启用 beta 分组<br />false 表示不启用 beta 分组</td>
</tr>
<tr>
<td>needConfirm</td>
<td>是否启用分组确认。启用后每一批次模块发布运维后，都会暂停，修改 ModuleDeployment.spec.pause 字段为 <strong>false</strong> 后，则运维继续</td>
<td>true 或 false</td>
<td>true 表示启用分组确认<br />false 表示不启用分组确认</td>
</tr>
<tr>
<td>grayTime</td>
<td>每一个发布运维批次完成后，sleep 多少时间才能继续执行下一个批次</td>
<td>0 - N</td>
<td>批次间的灰度时长，单位秒，0 表示批次完成后立即执行下一批次，N 表示批次完成后 sleep N 秒再执行下一批次</td>
</tr>
</tbody>
</table>
<h2 id="调度策略">调度策略</h2>
<p>可以为基座 K8S Pod Deployment 配置 Label &ldquo;serverless.alipay.com/max-module-count&rdquo;，指定每个 Pod 最多可以安装多少个模块。支持配置为 0 - N 的整数。模块支持打散调度和堆叠调度。<br />
<strong>打散调度</strong>：设置 ModuleDeployment.spec.schedulingStrategy.schedulingPolicy 为 <strong>scatter</strong>。打散调度表示在模块上线、扩容、替换时，优先把模块调度到模块数最少的机器上去安装。<br />
<strong>堆叠调度</strong>：设置 ModuleDeployment.spec.schedulingStrategy.schedulingPolicy 为 <strong>stacking</strong>。堆叠调度表示在模块上线、扩容、替换时，优先把模块调度到模块数最多且没达到基座 max-module-count 上限的机器上去安装。</p>
<h2 id="保护机制">保护机制</h2>
<p><em>(正在开发中，10.15 上线)</em> 您可以配置 ModuleDeployment.spec.maxUnavailable 指定模块在发布运维过程中，最多有几个模块副本可以同时处在不可用状态。模块发布运维需要更新 K8S Service 并卸载模块，会导致该模块副本不可用。<strong>配置为 50%</strong> 表示模块发布运维的一个批次，必须保证<strong>至少 50% 的模块副本可用</strong>，否则 ModuleDeployment.status 会展示报错信息。</p>
<h2 id="对等和非对等">对等和非对等</h2>
<p>您可以配置 ModuleDeployment.spec.replicas 指定模块采用对等还是非对等部署架构。<br />
<strong>非对等架构</strong>：设置 ModuleDeployment.spec.replicas 为 **0 - N **表示非对等架构。非对等架构下必须要为 ModuleDeployment、ModueRepicaSet 设置副本数，因此非对等架构下支持模块的扩容和缩容操作。<br />
<strong>对等架构</strong>：设置 ModuleDeployment.spec.replicas 为 **-1 <strong>表示对等架构</strong>。**对等架构下，K8S Pod Deployment 有多少副本数模块就自动安装到多少个 Pod，模块的副本数始终与 K8S Pod Deployment 副本数一致。因此对等架构下不支持模块的扩缩容操作。<em>对等架构正在建设中，预计 10.30 发布。</em></p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-24eb3a9c0234e21473eec787d4ae6d7a">5.6 - 独立使用 Arklet</h1>
    
	<p>Arklet 作为 SOFAServerless 模块发布运维的 Agent（定位类似 K8S 的 Kubelet），可以完全脱离 ModuleController 独立使用。它暴露了一组安装卸载模块的 HTTP 接口，从而可以让 SOFAServerless 对接到您自己的发布运维平台，<a href="https://github.com/sofastack/sofa-serverless/blob/feature.arklet_v1/arklet/README.md">接口文档详见此处</a>。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-c588ae48a684af6c4c57ee4d9aae6ce4">5.7 - 模块信息查看</h1>
    
	<h4 id="查看某个基座上所有安装的模块名称和状态">查看某个基座上所有安装的模块名称和状态</h4>
<pre tabindex="0"><code>kubectl get module -n &lt;namespace&gt; -l serverless.alipay.com/base-instance-ip=&lt;pod-ip&gt; -o custom-columns=NAME:.metadata.name,STATUS:.status.status
</code></pre><p>或</p>
<pre tabindex="0"><code>kubectl get module -n &lt;namespace&gt; -l serverless.alipay.com/base-instance-name=&lt;pod-name&gt; -o custom-columns=NAME:.metadata.name,STATUS:.status.status
</code></pre><h4 id="查看某个基座上所有安装的模块详细信息">查看某个基座上所有安装的模块详细信息</h4>
<pre tabindex="0"><code>kubectl describe module -n &lt;namespace&gt; -l serverless.alipay.com/base-instance-ip=&lt;pod-ip&gt;
</code></pre><p>或</p>
<pre tabindex="0"><code>kubectl describe module -n &lt;namespace&gt; -l serverless.alipay.com/base-instance-name=&lt;pod-name&gt;
</code></pre><p>替换<code>&lt;pod-ip&gt;</code>为需要查看的基座ip，<code>&lt;pod-name&gt;</code>为需要查看的基座名称，<code>&lt;namespace&gt;</code>为需要查看资源的namespace</p>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-cbb99adb1eb306a588e034d68e0481d8">5.8 - 模块Service</h1>
    
	<h2 id="moduleservice-简介">ModuleService 简介</h2>
<p>K8S 通过 <a href="https://kubernetes.io/docs/concepts/services-networking/service/">Service</a> ，将运行在一个或一组 Pod 上的网络应用程序公开为网络服务。
模块也支持 Module 相关的 Service ，在模块发布时自动创建一个 service 来服务模块，将安装在一个或一组 Pod 的模块公开为网络服务。
具体见：OperationStrategy.ServiceStrategy</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">serverless.alipay.com/v1alpha1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ModuleDeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/instance</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/part-of</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/managed-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">kustomize</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">app.kubernetes.io/created-by</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">module-controller</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">moduledeployment-sample-provider</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">baseDeploymentName</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dynamic-stock-deployment</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">template</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">module</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">provider</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;1.0.2&#39;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">url</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">replicas</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">operationStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">needConfirm</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">grayTimeBetweenBatchSeconds</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">120</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">useBeta</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">batchCount</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">upgradePolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">install_then_uninstall</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">serviceStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">enableModuleService</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">port</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">      </span><span style="color:#204a87;font-weight:bold">targetPort</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">schedulingStrategy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">schedulingPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">scatter</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><h2 id="字段解释">字段解释</h2>
<p>OperationStrategy.ServiceStrategy 字段解释如下：</p>
<table>
<thead>
<tr>
<th></th>
<th>字段解释</th>
<th>取值范围</th>
</tr>
</thead>
<tbody>
<tr>
<td>EnableModuleService</td>
<td>开启模块service</td>
<td>true or false</td>
</tr>
<tr>
<td>Port</td>
<td>公开的端口</td>
<td>1 到 65535</td>
</tr>
<tr>
<td>TargetPort</td>
<td>pod上要访问的端口</td>
<td>1 到 65535</td>
</tr>
</tbody>
</table>
<h2 id="示例">示例</h2>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment_provider.yaml --namespace yournamespace
</span></span></code></pre></div><p>自动创建的模块的 service</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">apiVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">v1</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">kind</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">metadata</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">creationTimestamp</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;2023-11-03T09:52:22Z&#34;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">dynamic-provider-service</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">namespace</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">default</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">resourceVersion</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;28170024&#34;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">uid</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">1f85e468-65e3-4181-b40e-48959a069df5</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">spec</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">clusterIP</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">10.0.147.22</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">clusterIPs</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span>- <span style="color:#0000cf;font-weight:bold">10.0.147.22</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">externalTrafficPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Cluster</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">internalTrafficPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">Cluster</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">ipFamilies</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span>- <span style="color:#000">IPv4</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">ipFamilyPolicy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">SingleStack</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">ports</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">http</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">nodePort</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">32232</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">port</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">protocol</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">TCP</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">targetPort</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">8080</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">selector</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">module.serverless.alipay.com/dynamic-provider</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;true&#34;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">sessionAffinity</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">None</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">type</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">NodePort</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">status</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">  </span><span style="color:#204a87;font-weight:bold">loadBalancer</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>{}<span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div>
</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-68c3bb9b1561f186515e61704fac5511">5.9 - 所有 K8S 资源定义及部署方式</h1>
    
	<h3 id="资源文件位置">资源文件位置</h3>
<ol>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/crd/bases/serverless.alipay.com_moduledeployments.yaml">ModuleDeployment CRD 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/crd/bases/serverless.alipay.com_modulereplicasets.yaml">ModuleReplicaset CRD 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/crd/bases/serverless.alipay.com_moduletemplates.yaml">ModuleTemplate CRD 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/crd/bases/serverless.alipay.com_modules.yaml">Module CRD 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/rbac/role.yaml">Role 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/rbac/role_binding.yaml">RBAC 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/rbac/service_account.yaml">ServiceAccount 定义</a></li>
<li><a href="https://github.com/sofastack/sofa-serverless/blob/master/module-controller/config/samples/module-deployment-controller.yaml">ModuleController 部署定义</a></li>
</ol>
<h3 id="部署方式">部署方式</h3>
<p>使用 kubectl apply 命令，依次 apply 上述 8 个资源文件，即可完成 ModuleController 部署。</p>
<br/>
<br/>
</div>



    
	
  

    
	
  



          </main>
        </div>
      </div>
      <footer class="td-footer row d-print-none">
  <div class="container-fluid">
    <div class="row mx-md-2">
      <div class="col-6 col-sm-4 text-xs-center order-sm-2">
        
        
        
<ul class="td-footer__links-list">
  
  <li class="td-footer__links-item" data-bs-toggle="tooltip" title="通过社区交流群" aria-label="通过社区交流群">
    <a target="_blank" rel="noopener" href="/docs/contribution-guidelines/communication-channel/" aria-label="通过社区交流群">
      <i class="fab fa-twitter"></i>
    </a>
  </li>
  
</ul>

        
        
      </div>
      <div class="col-6 col-sm-4 text-end text-xs-center order-sm-3">
        
        
        
<ul class="td-footer__links-list">
  
  <li class="td-footer__links-item" data-bs-toggle="tooltip" title="看这里" aria-label="看这里">
    <a target="_blank" rel="noopener" href="/docs/contribution-guidelines/contribution/first-pr/" aria-label="看这里">
      <i class="fab fa-github"></i>
    </a>
  </li>
  
</ul>

        
        
      </div>
      <div class="td-footer__copyright-etc col-12 col-sm-4 text-center py-2 order-sm-2">
        <span>&copy; 2023 SOFAServerless 开源社区 保留所有权利</span>
        
        
      </div>
    </div>
  </div>
</footer>
    </div>
    
  <script src="/js/main.min.1eb4262674b2d02aa8d18559fef13b166dbdfa627fd0a495c66e11577c026aa3.js" integrity="sha256-HrQmJnSy0Cqo0YVZ/vE7Fm29&#43;mJ/0KSVxm4RV3wCaqM=" crossorigin="anonymous"></script>
<script src='/js/prism.js'></script>
<script src='/js/tabpane-persist.js'></script>

  </body>
</html>
